0

しばらく探しましたが、これに対する回答を提供する記事が見つからなかったので、重複していないことを願っています.

私は構造体でいくつかの P/Invoking を行ってきましたが、これは素晴らしいことであり、すべてですが、次にこれを見ました:

char* infoString[SIDTUNE_MAX_CREDIT_STRINGS];

ここで、SIDTUNE_MAX_CREDIT_STRINGS は 10 として定義されます。

したがって、すべてをインライン化すると、構造体メンバーは次のように定義されます。

char* infoString[10]

これは、これを解決しようと試みた他の問題とは少し異なるところです。

char* 配列には、他の C 文字列へのポインタが含まれています。

この特定のケースでは、インデックスの 3 つだけが使用され、残りは予約されています。インデックスは次のとおりです。

  • infoString[0] = 曲名

  • infoString[1] = アーティスト名

  • infoString[2] = 著作権/発行者。

C# からこれらの各文字列にアクセスできるように、これをどのように IP/Invoke しますか? それぞれを個別に返す C++ 関数を作成することはできません。

4

1 に答える 1

0

関数が のようなものであると仮定すると、は の配列を持つものとしてGetSongInfo(int songID, LPInfostring songinfo)定義できます。ただし、呼び出し元の関数は、返された文字列に割り当てられたメモリを解放することを期待する可能性があるため、メモリ リークに注意する必要があります。structIntPtr

ターゲット.h:

typedef struct SongInfo
{
    char* infoString[10];
} *LPSongInfo;

extern "C" __declspec(dllexport) int GetSongInfo(int songID, LPSongInfo info);

ターゲット.c:

extern "C" __declspec(dllexport) int GetSongInfo(int songID, LPSongInfo demo)
{
    demo->infoString[0] = "Hello world";
    demo->infoString[1] = "Hello 1";
    demo->infoString[2] = "Hello 2";

    return TRUE;
}

P/インボーク署名:

[DllImport("PInvokeDll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetSongInfo(int songID, out SongInfo ts);

[StructLayout(LayoutKind.Sequential)]
struct SongInfo
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
    public IntPtr[] infoString;
};

使用例:

SongInfo siStruct;
var num2 = GetSongInfo(101, out siStruct);

// copy the results to managed memory
var results = new string[10];
for (int i = 0; i < 10; i++)
{
    if (siStruct.infoString[i] != IntPtr.Zero)
    {
        // if these were Unicode strings, this would change to PtrToSTringUni
        results[i] = Marshal.PtrToStringAnsi(siStruct.infoString[i]);
    }
}

// results now holds the .Net strings
// if there is an expectation of the caller to free the struct 
// strings, that should happen now

メモリを割り当てない関数の代わりに、次のような構造体を使用して文字列を自動的にマーシャリングできます。ただし、アンマネージ メモリは無条件に解放されますが、これは望ましい場合と望ましくない場合があります。

[StructLayout(LayoutKind.Sequential)]
struct SongInfo2
{
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPStr, SizeConst = 10)]
    public string[] infoString;
};
于 2013-06-06T17:45:54.107 に答える