繁体   English   中英

非托管导出,将字符串数组从C ++传递到C#

[英]Unmanaged Exports, passing an array of strings from C++ to C#

我正在使用Robert Giesecke的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);
    }

哪个好! 无论如何,任何人都可以帮助传入和传出字符串数组。 我很确定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 ++,所以暴露函数的参数类型是不可见的。

依赖沃克

谢谢

您可以使用IntPtr参数。

你必须分配非托管内存并将数组复制到该blob中。 否则GC会在某个时刻吃掉你的阵列。

使用数组的非托管导出

好吧,经过大量的混乱,我找到了解决方案:

//  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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM