-1

Win32 および CE 5 dll にコンパイルされた C++ コードがあります。両方のプラットフォーム用にコンパイルしていることがわかったので、必要に応じて分離するために C++ でプリプロセッサ定義を使用しています。

どちらの dll も C# から呼び出され、Win32 アプリの場合は .NET 3.5、CE アプリの場合は .NET 2.0 から呼び出されます。

Win32 ではすべてが完全に機能していますが、CE で dll 関数から戻るのに問題があります。C# から呼び出される dll 関数には、パラメーターとして構造体ポインターがあり、文字列型を含む構造体の内容は、dll 関数で変更されます。

C++ 関数の宣言は次のとおりです。

 DWORD __declspec(dllexport) ExtSomeFunc(LPTSTR szReader, MY_STRUCT* myStruct)

そしてC#で:

[DllImport("somelibrary.dll", EntryPoint = "ExtSomeFunc", CharSet = CharSet.Unicode)]
private static extern uint ExtSomeFunc([MarshalAs(UnmanagedType.LPWStr)] string szReaderName, ref MY_STRUCT myStruct);

C++ での構造体宣言は次のとおりです。

struct MY_STRUCT
{
    LPTSTR szString1;
    LPTSTR szString2;

    MY_STRUCT()
    {
        szString1 = new wchar_t[32];
        szString2 = new wchar_t[20];
    }

    ~MY_STRUCT()
    {
        delete []szString1;
        delete []szString1;
    }
};

そして C# では:

public struct MY_STRUCT
{
    [MarshalAsAttribute(UnmanagedType.LPWStr, SizeConst = 32)]
    public string szString1;

    [MarshalAsAttribute(UnmanagedType.LPWStr, SizeConst = 20)]
    public string szString2;

    public MY_STRUCT(string szInit)
    {
        this.szString1 = szInit;
        this.szString1 = szInit;
    }
}

C# で関数を呼び出す方法は次のとおりです。

 string szReader = "SomeDeviceName";
 uint uiRet = 0; 
 MY_STRUCT myStruct = new MY_STRUCT("");

 uiRet = ExtSomeFunc(szReader, ref myStruct);

つまり、構造体の文字列に長さ 6 を超える文字列を入力しようとすると、

wcscpy(myStruct->szString1,  L"1234567");

また

StringCchCopyW(myStruct->szString1, sizeReq+1, L"abcdefg");

C# が dll 関数から戻ることはありません。いくつかのテスト ファイルのログを使用すると、文字列が入力されて関数が完了したことを確認できますが、C# が復帰するときにハングするだけであり、回復するには CE デバイスの電源を入れ直す必要があります。

ここ数日頭を叩いています。それは明らかに.NET 2.0またはCE 5のいずれかで発生し、どちらを修正するかはわかりません。

前もって感謝します!

4

1 に答える 1

0

ツアーの前に c# 構造体定義を追加してみてください:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
  • pack の値は、構造体のバイト アラインメントでなければなりません。
于 2013-04-25T08:40:37.547 に答える