【问题标题】:Passing values and pointers between a c# and a c function在 c# 和 c 函数之间传递值和指针
【发布时间】: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

标签: c# c++ c


【解决方案1】:

这至少是因为您的参数parser 的类型,它应该被声明为System.IntPtr 而不是void*

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-26
    • 2012-12-17
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多