1

関数ポインター(getNameFP )を持つ公開された関数(DllFunctionPoibnterGetName )を持つC ++ DLL(SimpleDLL.dll )があります。関数ポインターは、パラメーターとしてchar *を取ります(* char * name *)。

// C++ 
DllExport void DllFunctionPoibnterGetName( void (*getNameFP) (char * name, unsigned short * length ) ) {

    char name[1024];
    unsigned short length = 0 ; 
    getNameFP( name, &length ); 

    printf( "length=[%d] name=[%s]\n", length, name ); 
}

このC++DLLを使用したいC#アプリケーションがあります。

// C# 
public unsafe delegate void GetName( System.Char* name, System.UInt16* length); 
unsafe class Program
{
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void delegateGetName(System.Char* name, System.UInt16* length);

    [DllImport("SimpleDLL.dll", CharSet = CharSet.Ansi )]
    public static extern void DllFunctionPoibnterGetName([MarshalAs(UnmanagedType.FunctionPtr)] delegateGetName getName);

    static void Main(string[] args)
    {   
        DllFunctionPoibnterGetName(GetName); 
    }

    static void GetName(System.Char* name, System.UInt16* length)
    {
        // name = "one two three";
        *length = 10; 
    }   
}

現在、問題なく長さを設定できますが、名前を正しく設定する方法が見つからないようです。

私の質問は

  • char* nameを値に正しく設定するにはどうすればよいですか。
4

3 に答える 3

1

You don't need to use unsafe code. You can do it like this:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void delegateGetName(IntPtr name, out ushort length);
....
static void GetName(IntPtr name, out ushort length)
{
    byte[] buffer = Encoding.Default.GetBytes("one two three");
    length = (ushort)buffer.Length;
    Marshal.Copy(buffer, 0, name, buffer.Length);
}   

Although this interface design is just asking for a buffer overrun. How are you supposed to know how big the unmanaged buffer is? It would make more sense for the length parameter to be passed by ref. On input it would tell you how big the buffer is. On output you would have recorded how many bytes you copied into the buffer.

于 2012-11-09T18:46:24.710 に答える
1

char*をchar[]としてキャストします。それでうまくいくはずです。

于 2012-11-09T18:12:58.187 に答える
1

チャーをキャストしても効果はありません。char *データは、「アンマネージ」のネイティブデータです。また、C#は「マネージド」の.NETデータを使用します。

呼び出しのラッパーを作成し、marschallを使用してデータを「アンマネージド」から「マネージド」に変換する必要があります。

于 2012-11-09T18:39:11.643 に答える