含传递String数组和整数数组为C一结构++ DLL [英] Passing a Structure containing an array of String and an array of Integer into a C++ DLL

查看:120
本文介绍了含传递String数组和整数数组为C一结构++ DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

,这里的code:

在C ++ DLL:

struct APP_PARAM
{
    int numData;
    LPCSTR *text;
    int *values;
};

int App::StartApp(APP_PARAM params)
{
    for (int i = 0; i < numLines; i++)
    {
        OutputDebugString(params.text[i]);
    }
}

在VB.NET:

  <StructLayoutAttribute(LayoutKind.Sequential)> _
  Public Structure APP_PARAM
    Public numData As Integer
    Public text As System.IntPtr
    Public values As System.IntPtr
  End Structure

  Declare Function StartApp Lib "AppSupport.dll" (ByVal params As APP_PARAM) As Integer

  Sub Main()

    Dim params As APP_PARAM
    params.numData = 3

    Dim text As String() = {"A", "B", "C"}
    Dim textHandle As GCHandle = GCHandle.Alloc(text)
    params.text = GCHandle.ToIntPtr(textHandle)

    Dim values As Integer() = {10, 20, 30}
    Dim valuesHandle As GCHandle = GCHandle.Alloc(values)
    params.values = GCHandle.ToIntPtr(heightHandle)

    StartApp(params)

    textHandle.Free()
    valuesHandle.Free()

  End Sub

我查了一下C ++面,从OutputDebugString的输出是垃圾,文字数组包含随机字符。什么是做到这一点的正确方法?

I checked the C++ side, the output from the OutputDebugString is garbage, the text array contains random characters. What is the correct way to do this?

推荐答案

GCHandle.Alloc 分配指定的对象,其中的一个普通手柄创建一个句柄管理对象.. 。其中$ p $被收集pvents管理对象

什么你要找的是 System.Runtime.InteropServices.Marshal 的方法,它允许你做的事情一样复制管理对象由非托管$访问的存储器C $℃。不幸的是,根据,指针在你的结构使其成为一个有点难度比很多其他的事情元帅(在这个意义上,许多其他的事情可以使用相应的P为自动编组/ Invoke的属性),但它仍然是可能的。我已经试过了这一点,它的工作原理:

What you're looking for is the methods from System.Runtime.InteropServices.Marshal, which allow you to do things like copy managed objects to memory accessible by unmanaged code. Unfortunately, according to this, the pointers in your struct make it a little harder to marshal than many other things (in the sense that many other things can be automatically marshalled using the appropriate P/Invoke attributes), but it's still possible. I've tried this out and it works:

APP_PARAM param = new APP_PARAM();
string[] text = new string[] { "A", "B", "C" };
param.numData = text.Length;

// Manually allocate an array of pointers, one for each string.  arr holds the array's address.
IntPtr arr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * text.Length);
try
{
  param.text = arr;

  IntPtr[] unmanagedText = new IntPtr[text.Length];
  try
  {
    // Create a null-terminated ANSI string in unmanaged memory for each element in text.
    for (int i = 0; i < text.Length; i++)
      unmanagedText[i] = Marshal.StringToHGlobalAnsi(text[i]);
    // Copy the addresses of the unmanaged strings into the manually allocated array.
    // I don't know of any way to make an unmanaged copy of a managed array in one call.
    Marshal.Copy(unmanagedText, 0, arr, unmanagedText.Length);

    // param now looks like what the C++ code is expecting (except for the array of int).
    StartApp(param);
  }
  finally
  {
    foreach (IntPtr str in unmanagedText)
      Marshal.FreeHGlobal(str);
  }
}
finally
{
  Marshal.FreeHGlobal(arr);
}

你必须有类似的分配/释放code你的int类型数组,有自己的try / finally块,以确保FreeHGlobal被调用。

You'll have to have similar allocation/free code for your array of int values, with its own try/finally blocks to make sure FreeHGlobal is called.

这篇关于含传递String数组和整数数组为C一结构++ DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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