我想在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#?
谢谢
答案 0 :(得分: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,那么你将被回调所吸引。您最好尝试使用明确的托管/非托管边界创建一个以不那么繁琐的方式实现API的C ++ / CLI库。
答案 1 :(得分:0)
char []是一个字符串。
看起来你正在定义一个指向char []的指针。在C中,这是阵列数组,对吧? 所以在C#中它只是:
String[] options = {
"document_root", "/var/www",
"listening_ports", "80,443s",
NULL
};
希望它有所帮助。
问候。
答案 2 :(得分: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 }
作为选项。
答案 3 :(得分: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做任何事情,但这不适用于你的情况。
答案 4 :(得分:0)