我想在 C# 中实现 Mongoose (http://code.google.com/p/mongoose/) 绑定(bind)。有一些示例,但它们不适用于当前版本。
这是我当前的函数调用:
[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#?
谢谢
最佳答案
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。
你在做函数指针吗?这才是真正的挑战所在。与其说是来自声明和编码(marshal),不如说是来自指针生命周期问题。如果 mg_start 持有委托(delegate)的非托管版本,您可能会发现 thunk 会在您身上进行垃圾收集,无论文档如何说明。我们经常看到这种情况发生,因此我们在可能的情况下重新构建了底层粘合剂,以不使用这种代码风格。
一般来说,如果 API 是一个包含大量回调的聊天 API,那么您将会被回调淹没。您最好尝试创建一个 C++/CLI 库,以一种不那么繁琐的方式实现 API,并具有明确的托管/非托管边界。
关于C# 相当于 C const char**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13144435/