2

私はC++でDLLを作成しました。関数の1つは、文字配列に書き込みます。

C++関数

EXPORT int xmain(int argc, char argv[], char argv2[])
{
    char  pTypeName[4096];
    ...
    //Other pTypeName ends up populated with "Portable Network Graphics"
    //This code verifies that pTypeName is populated with what I think it is:
    char szBuff[64];
    sprintf(szBuff, pTypeName, 0);
    MessageBoxA(NULL, szBuff, szBuff, MB_OK);
    //The caption and title are "Portable Network Graphics"

    ...
    //Here, I attempt to copy the value in pTypeName to parameter 3.
    sprintf(argv2, szBuff, 0);

    return ret;
}

C#インポート

    //I believe I have to use CharSet.Ansi because by the C++ code uses char[],
    [DllImport("FirstDll.dll", CharSet=CharSet.Ansi)]
    public static extern int xmain(int argc, string argv, ref string zzz);

C#関数

private void button2_Click(object sender, EventArgs e)
{
    string zzz = ""; 
    int xxx = xmain(2, @"C:\hhh.bmp", ref zzz);
    MessageBox.Show(zzz);

    //The message box displays
    //MessageBox.Show displays "IstuÈst¼ÓstÄstlÄstwÄstiÑstõÖstwÍst\
    // aÖst[ÖstÃÏst¯ÄstÐstòÄstŽÐstÅstpÅstOleMainThreadWndClass"

}

参照によってC#からパラメーターを渡そうとし、C++DLLにパラメーターを設定させました。DLLで値が正しいことを確認しましたが、gibberishがC#アプリケーションに渡されます。

正しい文字列値をC#文字列に書き込むにはどうすればよいですか?

4

2 に答える 2

5

を使用しStringBuilderて、ネイティブコードが入力できる文字配列を渡します(固定長文字列バッファを参照)。

関数を宣言します。

[DllImport("FirstDll.dll", CharSet=CharSet.Ansi)]
public static extern int xmain(int argc, string argv, StringBuilder argv2);

これを使って:

// allocate a StringBuilder with enough space; if it is too small,
// the native code will corrupt memory
StringBuilder sb = new StringBuilder(4096);
xmain(2, @"C:\hhh.bmp", sb);
string argv2 = sb.ToString();
于 2012-06-01T21:08:58.173 に答える
2

DLLImport呼び出しに他の情報を提供します。私自身の次の例を見てください。

[DllImport("tcpipNexIbnk.dll", EntryPoint = "SendData", CallingConvention = CallingConvention.Cdecl)]
    public static extern int Send([MarshalAs(UnmanagedType.LPWStr)]string message);

CallingConventionパラメーターの2つに注意してください。CallingConvention=CallingConvention.Cdecl)

そのままお使いください。

そして、c#文字列型のすぐ後ろで、MarshalAS命令を使用してさまざまなアンマネージ型で遊ぶことができます。これにより、C#文字列パラメーターがC++プログラムにあるネイティブ文字列型にキャストされます。

public static extern int Send([MarshalAs(UnmanagedType.LPWStr)]string message);

それが役に立てば幸い。

于 2012-06-01T19:29:29.810 に答える