【发布时间】:2019-11-13 20:44:11
【问题描述】:
我正在尝试使用开源 DLL 在 C# 大学项目中的不同方言之间转换 SQL 查询。我在 dll 中有一个函数,它需要一个指向对象的 void 类型指针。我在 c# 中找不到合适的类型来调用此函数。
我尝试使用 IntPtr 作为指向对象的所需指针,但出现以下错误
对 PInvoke 函数“WindowsFormsApp1!WindowsFormsApp1.Form1::SetParserTypes”的调用使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。
c/c++ 中的函数:
void SetParserTypes(void *parser, short source, short target)
{
if(parser == NULL)
return;
SqlParser *sql_parser = (SqlParser*)parser;
// Run conversion
sql_parser->SetTypes(source, target);
}
我试图在 c# 中使用的函数:
[DllImport(dllName: "DLL_LOCATION", EntryPoint = "SetParserTypes")]
public unsafe static extern void SetParserTypes(void *parser , short source, short target);
我这样调用这个函数:
SetParserTypes(&parserObj, 1,2);
在c#中调用函数时出现以下异常
托管调试助手“PInvokeStackImbalance”:“对 PInvoke 函数“WindowsFormsApp1!WindowsFormsApp1.Form1::SetParserTypes”的调用使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。'
【问题讨论】:
-
我将专注于 检查调用约定 匹配的部分。您没有在发布的代码中说明您使用的调用约定。
-
parserObj 是从哪里来的?
-
我从 DLL 中的另一个函数获取 parserObj。我正在使用 IntPtr 来存储该对象@JeffRSon
-
我不明白为什么它有效,但它确实有效。 @TimurKukharskiy