nal*_*d88 2 c# c++ dll pinvoke marshalling
我有一个我编写和测试的无人C++ DLL.在无人控制台应用程序中构建和运行时,无人管理的代码很好用.功能声明如下所示.
#ifndef IMPORT_MYLIB
# define MYLIB_API __declspec(dllexport)
#else
# define MYLIB_API __declspec(dllimport)
#endif
namespace gsod_data_parsing {
extern "C"
{
MYLIB_API int parse_raw_gsod_file_nocb(
const char *path,
int temp_threshold
);
}
}
Run Code Online (Sandbox Code Playgroud)
我试图从托管应用程序调用它.我在我的C#文件中声明了这个函数,如下所示:
[DllImport("GSODDLL.dll")]
public static extern int parse_raw_gsod_file_nocb(
[MarshalAs(UnmanagedType.LPStr)] string path,
int temp_threshold
);
Run Code Online (Sandbox Code Playgroud)
然后,这些函数将在几个并行任务上执行,如下所示:
// Start a task - this runs on the background thread...
task1 = Task.Factory.StartNew(() =>
{
int t1 = parse_raw_gsod_file_nocb(filePaths[i], this._frostTemp);
return (t1 == 0);
}, this._tokenSource.Token);
Run Code Online (Sandbox Code Playgroud)
它似乎一开始运行正常但后来(我相信函数执行完毕后)我得到以下错误.
调用PInvoke函数'Database Creator!Database_Creator.Form1 :: parse_raw_gsod_file_nocb'使堆栈失去平衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.
有人有主意吗?谢谢
所以事实证明我的问题是由于调用约定不匹配.根据这个文档,Windows中C/C++程序的默认调用约定是Cdecl.此外,根据该文档,PInvoke的默认调用约定是StdCall.我最初没有指定任何调用约定,因此它默认为StdCall.由于这些约定指定了在函数调用之后如何清理堆栈,因此在函数执行结束时抛出错误是有道理的.
将我的PInvoke声明更改为此修复了我的问题:
[DllImport("GSODDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int parse_raw_gsod_file_nocb(
[MarshalAs(UnmanagedType.LPStr)] string path,
int temp_threshold
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2977 次 |
| 最近记录: |