簡體   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