C# 调用C++;C语言中的动态链接库# 问题是,我有一个C++的DLL,我想用在我的C项目中。

C# 调用C++;C语言中的动态链接库# 问题是,我有一个C++的DLL,我想用在我的C项目中。,c#,dll,interop,pinvoke,dllimport,C#,Dll,Interop,Pinvoke,Dllimport,有问题的函数具有原型: int MRK3LINK_Open(void (*pfLog)(const char* s),void (*pfErrorOut)(const char* s)); 文件指出: pfLog是指向const char*类型的日志处理程序函数的指针 pfErrorOut是指向const char*类型的错误输出处理程序函数的指针 以及如何从C++调用DLL函数的示例: static void _LogHandler(const char* sLog) {

有问题的函数具有原型:

 int MRK3LINK_Open(void (*pfLog)(const char* s),void (*pfErrorOut)(const char* s));     
文件指出:

  • pfLog是指向const char*类型的日志处理程序函数的指针
  • pfErrorOut是指向const char*类型的错误输出处理程序函数的指针
以及如何从C++调用DLL函数的示例:

static void _LogHandler(const char* sLog) {
   printf(sLog);
}

static void _ErrorOutHandler(const char* sError) {
   MessageBox(NULL, sError, "2-Link", MB_OK);
}

MRK3LINK_Open(_LogHandler, _ErrorOutHandler);
这件事我已经坚持了两天了。你能给我一些建议吗


谢谢。

这两个参数是函数指针。它们将在C++中映射到委托。像这样:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LogHandlerDelegate(string str);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ErrorOutHandlerDelegate(string error);
那么您导入的函数是:

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern int MRK3LINK_Open(
    LogHandlerDelegate LogHandler,
    ErrorOutHandlerDelegate ErrorOutHandler
); 

然后以常规方式创建代理并将其传递给
MRK3LINK\u Open
。如果非托管代码引用代理并在
MRK3LINK\u Open
返回后调用它们,请确保存储对代理的引用。否则,垃圾收集器可能会收集它们。

两个可能的错误,您发布的内容远远不够。您可能忘记了委托声明上的[UnmanagedFunctionPointer]属性,以确保CLR知道这是CallingConvention.Cdecl函数指针。您没有将委托对象存储在任何位置,因此它们会被垃圾收集,当C代码进行回调时会使程序崩溃。谢谢您的建议,您是对的。谢谢您的回答,我现在已经得到了:)