2

我想在 C# 中实现 Mongoose (http://code.google.com/p/mongoose/) 绑定。有一些示例,但它们不适用于当前版本。

这是我当前的函数调用:

[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] private static extern IntPtr mg_start(int zero, Nullable, string options);

(工作)C等价物将是:

const char *options[] = {
     "document_root", "/var/www",
     "listening_ports", "80,443s",
     NULL
   };
struct mg_context *ctx = mg_start(&my_func, NULL, options);

其中 mg_start 定义为:

struct mg_context *mg_start(mg_callback_t callback, void *user_data,
                            const char **options);

您可以在这里找到整个 C 示例: https ://svn.apache.org/repos/asf/incubator/celix/trunk/remote_services/remote_service_admin_http/private/include/mongoose.h

如何转移const char *options[]到 c#?

谢谢

4

5 回答 5

3
DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)]
private static extern IntPtr mg_start(IntPtr callback, IntPtr userData,
    [In][MarshalAsAttribute(UnmanagedType.LPArray,
                            ArraySubType=UnmanagedType.LPStr)] string[] options);

没有尝试过,但我认为这可以让你到达那里。如果您想在 C 调用中使用 unicode,您可能需要将 ArraySubType 设置为 LPWStr。使它成为 LPStr 为您提供 ANSI。

你在做函数指针吗?这才是真正的挑战所在。与其说是声明和编组,不如说是指针寿命问题。如果 mg_start 保留委托的非托管版本,您可能会发现 thunk 会在您身上收集垃圾,尽管文档说了什么。我们经常看到这种情况发生,因此我们尽可能地重新设计了底层粘合剂以不使用这种代码风格。

一般来说,如果 API 是一个带有大量回调的健谈 API,那么您将被回调所困扰。您最好尝试创建一个 C++/CLI 库,该库以一种更简洁的方式实现 API,并具有明确的托管/非托管边界。

于 2012-10-30T17:55:02.477 回答
0

在 C# 中,char 是 Unicode 字符,因此由两个字节组成。在这里使用字符串不是一个选项,但您可以使用 Encoding.ASCII 类将 unicode 字符串的 ASCII 表示形式获取为字节数组:

byte[] asciiString = Encoding.ASCII.GetBytes(unicodeString);

C# 的数组是引用,也就是 C 中的指针,因此您可以将代码编写为:

byte[][] options = {
    Encoding.ASCII.GetBytes("document_root"),
    Encoding.ASCII.GetBytes("/var/www"),
    Encoding.ASCII.GetBytes("listening_ports"),
    Encoding.ASCII.GetBytes("80,443s"),
    null
};

除了使用只读索引器和私有字节数组创建包装类之外,您无法对 const 做任何事情,但这不适用于您的情况。

于 2012-10-30T17:39:45.850 回答
0

我只是想建议在项目页面上使用 C# 绑定,它们具有以下功能:

  • Python 和 C# 绑定

你试过这个吗?

于 2012-10-30T17:40:41.803 回答
0

C# 中的 char[] 是一个字符串。

看起来您正在定义一个指向 char[] 的指针。在 C 中,这是 Array of Arrays,对吧?所以在 C# 中它只是:

String[] options = {
 "document_root", "/var/www",
 "listening_ports", "80,443s",
 NULL
};

希望能帮助到你。

问候。

于 2012-10-30T17:32:54.633 回答
0

尝试

[DllImport("_mongoose",CallingConvention=CallingConvention.Cdecl)] 
private static extern IntPtr mg_start(int zero, IntPtr userData, string[] options);

IntPtr.Zero用作userdata. 和类似的东西

new [] { "document_root", "/var/www", "listening_ports", "80,443s", null }

作为选项。

于 2012-10-30T17:33:14.813 回答