在c#和c函数之间传递值和指针

Passing values and pointers between a c# and a c function

本文关键字:指针 函数 之间      更新时间:2023-10-16

我试图使用开源DLL在C#大学项目中的不同方言之间转换SQL查询。我在DLL中具有一个函数,该功能需要一个void类型的指针指向对象。我找不到C#中的合适类型用于调用此功能。

我尝试使用INTPTR作为对象所需的指针,但我会收到以下错误

呼叫pinvoke函数'windowsformsapp1!windowsformsapp1.form1.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.form1 :: setparsertypes'使堆栈不平衡。这可能是因为托管PinVoke签名与非托管目标签名不符。检查PINVOKE签名的调用约定和参数是否与目标不受管理的签名相匹配。'

至少是由于您的参数parser的类型,应将其声明为System.IntPtr而不是void*

有关C#和C 之间的类型映射的更多信息,请查看:https://learn.microsoft.com/en-us/dotnet/framework/framework/interop/interop/marshaling-data-data-with-plat-plat--platform-ing.>