【问题标题】:Access C++ DLL from C# program从 C# 程序访问 C++ DLL
【发布时间】:2018-09-23 18:55:10
【问题描述】:

我对互操作非常陌生,在定义从 C++ DLL 导入的 dll 时遇到问题。 DLL的文档如下:

bool __stdcall __declspec(dllexport) InitHW(char *name, char *model, int& type)

所以我尝试的代码如下,它给出了一个 system.AccessViolation 异常:

[DllImport("extIO_IC7610.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern bool InitHW(string name, string model, int type);

private unsafe void Initialize()
{
    try
    {
        bool result;

        string name = "Test";
        string model = "Model";
        int type = 3;

        result = InitHW(name, model, type);
    }
    catch (Exception ex)
    {

    }
}

我刚刚意识到这应该返回数据。 有人可以在这里告诉我我理解中的错误吗? 谢谢,汤姆

根据 cmets,我将其更改为如下所示:

[DllImport("extIO_IC7610.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)] 
public unsafe static extern bool InitHW(string name, string model, ref int type);

unsafe private void Initialize())
{

    try
    {
        bool result;

        string name = ""; 
        string model = ""; 
        int type = 3;
        result = InitHW(name, model, ref type);

    }
    catch (Exception ex)
    {

    }
}

这仍然不起作用。我现在收到一个错误,由于签名不匹配,堆栈不平衡。我认为字符串已正确完成,但 &int 参数可能仍然是一个问题。 汤姆

【问题讨论】:

  • 我认为你需要 ref int type... 不确定其余部分,但我认为不需要 unsafe
  • 除了已经提到的ref int,请注意本机C++ 函数的返回类型是C++ 数据类型bool。您的 DLLImport 必须专门考虑这一点(C# 数据类型 bool 的默认编组是本机 WinAPI 类型 BOOL,它不同于 C++ 数据类型 bool)。为什么以及如何做到这一点,请参见此处:blogs.msdn.microsoft.com/jaredpar/2008/10/14/…;或在这里查看:stackoverflow.com/questions/4608876/…
  • 还要确保你指定了你的 dll 期望的字符串编码!
  • 仍然出现错误
  • 越来越近了。我需要使用 CallingConvention.StdCall。这似乎有效,我没有错误,但所有返回的参数都是空的。所以参数还是有问题。

标签: c# interop dllimport


【解决方案1】:

好吧,我解决了。这里有一些提示,但没有什么真正正确的。在环顾过去几个小时后,这是解决方案:

    [DllImport("extIO_IC7610.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
    [return: MarshalAs(UnmanagedType.I1)] 
    public unsafe static extern bool InitHW(StringBuilder name,  StringBuilder model, int* type);

unsafe void Initialize()
{
           bool result;

            int type = 0;
            var name = new StringBuilder(250);
            var model = new StringBuilder(250);

            result = InitHW(name, model, &type);

            string _name = name.ToString();
            string _model = model.ToString();

}

【讨论】:

  • 不需要不安全。使用 out int 或 ref int。
  • 你是对的。我确实有其他需要不安全的功能。我只是没有把它们放进去。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
相关资源
最近更新 更多