1

char**C のベース配列を C# の同等の型に 変換するにはどうすればよいですか?

char**バッファを取得して適切なデータで埋める関数を持つ DLL があります。

を使用して、C# アプリケーション内でこの DLL を使用しています。DllImport

問題は、そのような関数に対してreturn typeまたはを指定する必要があるときに始まります。argument type

C# のどの型が Cchar**配列と同等ですか?

何をマーシャリングし、どのようにマーシャリングする必要がありますか?

更新:
これは私のdll内にある私のC関数です:

CDLL_API wchar_t** GetResults(wchar_t* word, int* length, int threshold = 9);

そして、これら 2 つの関数は次の関数を呼び出して値を取得します。

wchar_t** xGramManipulator::CGetNextWordsList(const wchar_t* currentWord, int threshold)
{
    wstring str(currentWord);
    auto result = GetNextWordsList(str, threshold);

    return GetCConvertedString(result);
}

wchar_t ** xGramManipulator::GetCConvertedString(vector< wstring> const &input)
{
    DisposeBuffers();//deallocates the previously allocated cStringArrayBuffer.
    cStringArraybuffer = new wchar_t*[input.size()];
    for (int i = 0; i < input.size(); i++)
    {
        cStringArraybuffer[i] = new wchar_t[input[i].size()+1];
        wcscpy_s(cStringArraybuffer[i], input[i].size() + 1, input[i].c_str());
        cStringArraySize++;
    }
    return cStringArraybuffer;
}

私は wchar_T** を使用しましたが、C# 側に違いはないと思いました (C# はデフォルトで Unicode をサポートしているため! 異なる場合は、これにも対処してください)

4

1 に答える 1

3

コメントでは、この関数を扱うことに最も関心があると述べています。

CDLL_API wchar_t** GetResults(wchar_t* word, int threshold);

p/invoke マーシャラーが戻り値をマーシャリングすることは期待できません。これは手動で行う必要があります。さらに、現在設計されているため、関数を確実に呼び出すことはできません。これは、呼び出し元が返された配列の長さを取得する方法がないためです。配列の長さを呼び出し元に返すには、追加のパラメーターを追加する必要があります。

CDLL_API wchar_t** GetResults(wchar_t* word, int threshold, int* len);

C# 側では、次のように宣言します。

[DllImport(@"DllName.dll", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr GetResults(
    [MarshalAs(UnmanagedType.LPWStr)]
    string word,
    int threshold,
    out int len
);

DllImportまた、指定した呼び出し規約がネイティブ コードのものと一致していることを確認する必要があります。と仮定してcdeclいますが、確かなことはあなただけが知っています。

次のように呼び出します。

int len;
IntPtr results = GetResults(word, threshold, out len);
IntPtr[] ptrs = new IntPtr[len];
Marshal.Copy(results, ptrs, 0, len);
for (int i=0; i<len; i++)
{
    string item = Marshal.PtrToStringUni(ptrs[i]);
}

メモリ リークを回避するには、によって割り当てられたメモリの割り当てを解除する別の関数をエクスポートする必要がありますGetResults。呼び出しが終わったら、それを呼び出しPtrToStringUniます。

率直に言って、これは混合モードの C++/CLI ソリューションにより適しているように見えます。

于 2013-07-29T14:57:21.127 に答える