【问题标题】:Unmanaged Exports, passing an array of strings from C++ to C#非托管导出,将字符串数组从 C++ 传递到 C#
【发布时间】:2015-09-03 09:47:38
【问题描述】:

我使用Robert Giesecke's Unmanaged Exports 包能够从 C++ 调用到 C#。 这必须使用 C++ 中的 C 接口。我已经设法让大多数事情正常工作,通过搜索网络并在这里和那里收集一些东西......

extern "C"
{
    //  Simple
    __declspec(dllimport) int IntTest(int input);
    __declspec(dllimport) double DoubleTest(double input);

    //  Array of simple types in
    __declspec(dllimport) int passArray(int t[], int i, int xx);

    //  String in and out
    __declspec(dllimport) int PassStringIn(wchar_t* str);
    __declspec(dllimport) int PassStringOut(wchar_t** str);
    __declspec(dllimport) wchar_t* PassStringInOut(wchar_t* str);

    //  Array of strings types in
    //__declspec(dllimport) int passArrayStrings(char** t, int i);
}

....

//  Int in and out
int aa = IntTest(4);

//  Double in and out
double bb = DoubleTest(4.3);

//  Pass array in
int arr[4] = { 1,2,3,4 };
int cc = passArray(arr, 4, 0);

//  String in
wchar_t* a_str = L"input string from C++";
int dd = PassStringIn(a_str);

//  String out
wchar_t* b_str = L"not used";
int ee = PassStringOut(&b_str);

//  String in & out
wchar_t* d_str = L"bob";
wchar_t* result = PassStringInOut(d_str);

对应的C#

    [DllExport( CallingConvention = CallingConvention.Cdecl)]
    static int IntTest(int input)
    {
        return input + 1;
    }

    [DllExport(CallingConvention = CallingConvention.Cdecl)]
    static double DoubleTest(double input)
    {
        return input + 1;
    }

    [DllExport(CallingConvention = CallingConvention.Cdecl)]
    public static int passArray([In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]  int[] tab, int i, int x)
    {
        return tab[x];
    }

    [DllExport(CallingConvention = CallingConvention.Cdecl)]
    public static int PassStringIn( [MarshalAs(UnmanagedType.LPWStr)] string inputString)
    {
        Console.WriteLine("Hi, the string passed in was :" + inputString);
        return 1;
    }

    [DllExport(CallingConvention = CallingConvention.Cdecl)]
    static int PassStringOut([MarshalAs(UnmanagedType.BStr)] out string outputString)
    {
        Console.WriteLine("Hi, I will return the time from c#");
        outputString = DateTime.Now.ToLongTimeString();
        return 0; // indicates success
    }

    [DllExport(CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.LPTStr)]
    public static string PassStringInOut([MarshalAs(UnmanagedType.LPTStr)]string name)
    {
        return string.Format("Hello from .NET assembly, {0}!", name);
    }

Which was nice! 无论如何,任何人都可以帮助传入和传出字符串数组。我很确定 C# 部分应该是这样的:

    [DllExport(CallingConvention = CallingConvention.Cdecl)]
    public static int passArrayStrings( [In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 1)]  string[] tab, int i)
    {

        return 1;
    }

我需要 C++(C) 方面的帮助,了解如何构建字符串数组,以便正确编组它们。创建的混合模式程序集同时具有 C# 和 C 接口。由于它是 C 而不是 C++,因此公开函数的参数类型是不可见的。

谢谢

【问题讨论】:

    标签: c# c++ c c#-4.0 interop


    【解决方案1】:

    您可以使用 IntPtr 参数。

    无论如何,您都必须分配非托管内存并将数组复制到该 blob 中。否则 GC 会在某个时候吃掉你的数组。

    Unmanaged Exports with Arrays

    【讨论】:

    • 很高兴了解您认为我做错了什么。只是投反对票并没有真正的帮助吗?
    • 嗨罗伯特,我是提出这个问题的人,但我没有否决这个答案,不知道是谁投的?事实上,我只是刚刚登录到堆栈溢出并看到了你的答案。让我研究一下你的答案,然后回复你。谢谢肖恩
    • 嗨罗伯特,我终于搞定了。我使用了 BSTR 数组:
    【解决方案2】:

    好吧,经过一番折腾,我找到了解决方案:

    //  Array of strings types in
    __declspec(dllimport) int passArrayStrings(BSTR* bstrArray, int i);
    
    BSTR bstrArray[10] = { 0 };
    for (int i = 0; i < 10; i++)
    {
        bstrArray[i] = ::SysAllocString(L"My String.");
    }
    int ff = passArrayStrings(bstrArray, 10);
    for (int i = 0; i < 10; i++)
    {
        ::SysFreeString(bstrArray[i]);
    }
    

    在 c# 方面:

        [DllExport(CallingConvention = CallingConvention.Cdecl)]
        public static int passArrayStrings([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.BStr, SizeParamIndex = 1)]  string[] tab, int iSize)
        {
            return 1;
        }
    

    【讨论】:

      猜你喜欢
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 2013-02-09
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      相关资源
      最近更新 更多