使用dllimport从c#使用非托管c ++的麻烦 [英] trouble using unmanaged c++ from c# using dllimport

查看:177
本文介绍了使用dllimport从c#使用非托管c ++的麻烦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将C ++非托管dll导入C#[winform]时遇到问题。有人可以帮忙吗?

i am having trouble importing c++ unmanaged dll into C# [winform]. Can someone help?

基本上我只是想在c ++中创建一个字符串的safearray,并试图发送到C#。

Basically i am just trying to create a safearray of strings in c++ and trying to send it to C#.

这是我的c ++代码。

Here is my c++ code.

extern "C" __declspec(dllexport) BOOL GetStringArr(SAFEARRAY* arr)
{
SAFEARRAY*    myArray;
  SAFEARRAYBOUND  rgsabound[1];

  rgsabound[0].lLbound = 0;
  rgsabound[0].cElements = 5;

  myArray = SafeArrayCreate(VT_BSTR, 1, rgsabound);
  VARIANT* pvData = (VARIANT*)(myArray->pvData);

  pvData[0].vt = VT_BSTR;
  pvData[0].bstrVal = SysAllocString(L"FirstString");
  pvData[1].vt = VT_BSTR;
  pvData[1].bstrVal = SysAllocString(L"SecondString");
  pvData[2].vt = VT_BSTR;
  pvData[2].bstrVal = SysAllocString(L"ThirdString");
  pvData[3].vt = VT_BSTR;
  pvData[3].bstrVal = SysAllocString(L"FourthString");
  pvData[4].vt = VT_BSTR;
  pvData[4].bstrVal = SysAllocString(L"FifthString");

  arr = myArray;
  return true;
}

这是我的c#代码。

[DllImport("MyData.dll", EntryPoint = "GetStringArr")]
public static extern bool GetStringArr([MarshalAs(UnmanagedType.SafeArray)] out Array strServerList); 

我从C#调用GetStringArr时会遇到异常。我肯定有一些傻的我在做。有人可以帮忙吗?

i am getting exception when i call GetStringArr from C#. i am sure there is something silly i am doing. Can someone please help?

提前感谢。

推荐答案

C和.NET端的问题

Some problems on both the C and .NET side of things

在C端


  1. 参数间接错误。由于您在函数中分配了SAFEARRAY描述符,因此您需要一个SAFEARRAY **。

  2. SAFEARRAY未正确填充。您创建了基本类型为VT_BSTR的SAFEARRAY描述符,这意味着数据元素应为BSTR。

extern "C" __declspec(dllexport)
BOOL GetStringArr(SAFEARRAY** arr) 
{ 
  SAFEARRAY*    myArray; 
  SAFEARRAYBOUND  rgsabound[1]; 

  rgsabound[0].lLbound = 0; 
  rgsabound[0].cElements = 5; 

  myArray = SafeArrayCreate(VT_BSTR, 1, rgsabound); 
  BSTR* pvData = (BSTR*)(myArray->pvData); 

  pvData[0] = SysAllocString(L"FirstString"); 
  pvData[1] = SysAllocString(L"SecondString"); 
  pvData[2] = SysAllocString(L"ThirdString"); 
  pvData[3] = SysAllocString(L"FourthString"); 
  pvData[4] = SysAllocString(L"FifthString"); 

  *arr = myArray;
  return true; 
}

在.NET端


  1. 需要指定调用约定,否则会出现堆栈问题。

  2. 您应该设置SafeArraySubType

  3. 您可以使用 out string [] 获取指向SAFEARRAY的指针

  1. The Calling convention needs to be specified otherwise you will have stack issues
  2. You should set the SafeArraySubType
  3. You can use out string[] to get the pointer to the SAFEARRAY

.NET代码

.NET Code

  class Program
  {
    static void Main(string[] args)
    {
      string[] data;
      bool b = GetStringArr(out data);      
    }

    [DllImport("MyData.dll", 
               CallingConvention = CallingConvention.Cdecl)]
    public static extern bool GetStringArr(
      [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_BSTR)] 
      out string[] strServerList);    
  }

这篇关于使用dllimport从c#使用非托管c ++的麻烦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆