从C#调用非托管(C++)函数时发生PInvoke错误
PInvoke error when calling unmanaged (C++) function from C#
我有一个未经管理的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
);
}
}
我正试图从托管应用程序调用此。我在C#文件中这样声明函数:
[DllImport("GSODDLL.dll")]
public static extern int parse_raw_gsod_file_nocb(
[MarshalAs(UnmanagedType.LPStr)] string path,
int temp_threshold
);
这些功能随后在两个并行任务上执行,如下所示:
// 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);
它一开始运行得很好,但后来(我相信当函数执行完毕时(我出现了以下错误。
对PInvoke函数"数据库"的调用创造者!数据库创建者。表单1::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
);
相关文章:
- "error: no matching function for call to"构造函数错误
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- C++ OpenCV 卡尔曼滤波器构造函数错误
- C++:用户定义的显式类型转换函数错误
- C++ 合并字符串以'system'函数错误
- C++ wmain 函数错误时使用 Unicode
- 结构数组的构造函数错误,错误消息:没有构造函数实例与参数列表匹配
- C++ 中常量属性的初始化构造函数错误
- 线程 std::调用未知类型,无法专门化函数错误
- 表单显示对话框函数错误,并且不执行下面的语句
- 函数错误 C2059:语法错误:'>'不起作用
- STL向量上出现奇怪的复制构造函数错误
- C++ Visual Studio 重载函数错误:没有重载函数的实例与指定的类型匹配
- C++引用已删除函数错误
- 为什么通过带有文字编号的引用调用会出现"无匹配函数"错误?
- C++ 乘法定义的构造函数错误消息似乎错误
- 在 c++ 代码中将数组传递给函数错误
- FFMPEG avcodec_decode_video2函数错误代码
- 为什么我会收到转换函数错误