2017-05-26 12 views
0

私のC++の関数には次の構造体があります。構造体をC++関数に渡し、いくつかの変更を加えて同じ構造体を返す方法はありますか?

struct Cam 
{ 
    char ip[16]; 
    char login[16]; 
    char pass[16]; 
    char name[16]; 
}; 

後、私はここで

extern "C" __declspec(dllexport) Cam* AddCameraStruct1(Cam cam) 
{ 
//modify the cam object 
} 

クラス - 私のCPPから露出している方法であり、私はC#での構造体と関数を定義しています方法です。

[StructLayout(LayoutKind.Sequential)] 
    internal unsafe struct Cam 
    { 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
     public string ip; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
     public string login; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
     public string pass; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
     public string name; 
    } 

[DllImport(@"mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
    [return: MarshalAs(UnmanagedType.LPStruct)] 
    internal static extern IntPtr AddCameraStruct1(DPAPI.Cam*); 

これをC#で消費する方法はありません。間違っているかどうかをご提案ください。私は、次のエラーを取得しています

unsafe 
{ 
       DPAPI.Cam cam = new DPAPI.Cam(); 
       cam.ip = "192.168.0.232"; 
       cam.login = "admin"; 
       cam.pass = "admin"; 
       cam.name = "kekekeke"; 
       DPAPI.Cam* cam1 = (DPAPI.Cam*)DPAPI.AddCameraStruct1(cam); 
} 

-

ポインタと固定サイズのバッファが

危険な状況でのみ使用することができるが、のアドレスを取るのサイズを取得、またはへのポインタを宣言することはできません管理された型

+0

あなたの質問は不明です。これはどういう意味ですか?「これをC#でどのように消費するのか分かりません」どのようなエラーが出ますか? – nakiya

+0

私の更新された質問をご覧ください。 –

答えて

2

構造体から関数を返すことはできません。単純に構造体を参照渡しで渡すことができます(Windows API全体がBTWとして定義されている方法です)。ここで

は、構造体を宣言する文字セットは、ANSIであることを示すために忘れてはいけない方法です:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
internal struct Cam 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
    public string ip; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
    public string login; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
    public string pass; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] 
    public string name; 
} 
ここ

メソッドを宣言する方法である(参照引数は、*を使用してのようなものです):

ここで
[DllImport(@"mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
internal static extern void AddCameraStruct1(ref Cam pcam); 

は、C/C++でそれを宣言する方法である:ここでは

extern "C" __declspec(dllexport) void AddCameraStruct1(Cam *pcam) 
{ 
    strcpy_s(pcam->name, "hello"); // for example 
} 

はあなたがいない、それを呼び出す方法ですw:

var cam = new Cam(); 
cam.ip = "192.168.0.232"; 
cam.login = "admin"; 
cam.pass = "admin"; 
cam.name = "kekekeke"; 
AddCameraStruct1(ref cam); 
// cam.name is now "hello" 

コードでunsafeキーワードを使用する必要はありません。

+0

私は上記のキーワードを使って試してみましたが、refの代わりに使用するときのルールはきちんと働いていましたか? –

+0

構造体の配列をネイティブコードに送信するために呼び出しを変更する必要がある場合はどうすればいいですか?これは、IntPtrを配列に渡すことによって行うことができます。それをどうやって行うのか正確にはわかりません。 –

+2

refを使用すると、データを渡すだけでなく、渡します。それはあなたの質問でどのように見えたかです。それは基本的なC#です。これらの2つのキーワードに関するドキュメントを読んでください。 –

関連する問題