現在、C++ API用のC#ラッパーを作成していますが、この構造体に依存する特定の構造体と関数はデバッグ時に非常に奇妙なエラーを出しています。PInvokeからの奇妙なエラーstruct/function
C++構造体:
int __stdcall get_device_info(DeviceInfo di[], const int length_of_di_array, int* p_numValidDevices);
構造体及び機能のようなインポートされ:この関数に続い
typedef struct
{
unsigned __int handle;
char name[80];
unsigned int unique_ID;
} DeviceInfo;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DeviceInfo
{
public UInt32 handle;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 80)]
public String name;
public UInt32 unique_ID;
}
[DllImportAttribute("MyC++API.dll", EntryPoint = "get_device_info", CallingConvention = CallingConvention.StdCall)]
public static extern int get_device_info(ref DeviceInfo di, int length_of_di_array, ref numValidDevices);
この構造体及び機能の使用目的ちょうどボードImアクセスからいくつかのデバイス情報を取得することです。現在、私はC++の関数本体にアクセスすることはできないので、100%動作しているとしか思えません(C++でうまく動作します)。
構造体の配列を実行する関数を使用すると、探しているデータが出力されるだけでなく、実行時にエラーが発生してさまざまなエラーウィンドウが表示されるという問題があります。
C#コード:
static void Main()
{
int numValidDevices = 0; //initialize variable
DeviceInfo[] di = new DeviceInfo[16]; //max of 16 devices
for (int i = 0; i < numValidDevices; ++i) //sorts through all validated devices
{
rc = get_device_info(ref di[i], 16, ref numValidDevices); //accesses each device element and returns the data
Console.WriteLine("Handle: {0}\nName: {1}\nUnique ID: {2}", di[i].handle, di[i].name, di[i].unique_ID);
}
Console.ReadLine(); //stops console from closing prematurely
API_close(); //custom close function from the C++ API
}
エラーのデバッグ中(情報がまだ示されている): 「タイプ 'System.Threading.ThreadStateException' の未処理の例外は、System.dllの
で発生しました追加情報:スレッドは開始されていません。 「未処理の例外タイプの「システム:(情報が表示されない、プログラムの実行に失敗した)デバッグ中
はエラー「型 『System.ExecutionEngineException』の未処理の例外がmscorlib.dllで発生しました」。 mscorlib.dllでAccessViolationException 'が発生しました
追加情報:保護されたメモリを読み書きしようとしました。これは他のメモリが壊れていることを示していることがよくあります。
コンソールウィンドウを閉じるとき: '0x7c9113c0'の命令が '0x00000000'のメモリを参照しました。メモリを書き込めませんでした。 " (時には「書かれた」の代わりに「読む」と言います)。
私はのPInvokeに多くの研究を行い、Microsoft InteropAssistant applicationに出くわした、などthis oneなど様々なスタックオーバーフローの記事、およびthis postはイムがやって何にでも近いようだが、私はまだ元帥の使用方法に掘っていました.CoTaskMemAlloc/Free、それがanyhtingを行う場合でも参照してください...
これまで私の構造体と関数は正しいですが、私はIntPtrを使用する構造体を変更しようとしましたが、 di.name値とdi.unique_IDはジバリッシュになります(奇妙なことにディ。ハンドルが)有効なまま
C#コード:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DeviceInfo
{
public UInt32 handle;
IntPtr p_name;
public String name { get { return Marshal.PtrToStringAnsi(p_name); } }
public UInt32 unique_ID;
}
意図した出力:
Handle: 3126770193
Name: DEVICE_A
Unique ID: 12345678
のIntPtr出力:奇妙な
Handle: 3126770193
Name:
Unique ID: 1145128264
、エラーのどれでのIntPtr結果を使用して上記の通り、うまく動作します。 これは、文字列にC + + charをマーシャリングすることに問題があると考えていますが、マーシャリング、メモリ管理(問題はありませんか?)、または私が完全にキャッチしていない問題。
任意およびすべてのフィードバックは本当に
あなたは1つの参照を渡していますが、配列が必要です。 – leppie
また、Cで 'sizeof'がCで==' sizeof'であることを確認してください。名前が間違って宣言されていると思われます。代わりにbyte []を試して、値の配列サイズの定数を適用してください。 – leppie
質問を編集するのではなく、回答を投稿することになっています。あなたはそうしたいですか? –