19


6

DLLに次のC関数があるとします。

char * GetDir(char * path);

どのようにしてこの関数をC#にP / Invokeし、char *を適切に整列化しますか。 .NETはLPCTSTRの実行方法を知っているようですが、この関数を呼び出すときにNotSupportedExceptionが発生しないマーシャリングを見つけられないとき。

2 Answer


22


OregonGhostの答えは、GetDirから返されたchar *がHGlobalまたはLocalAllocに割り当てられている場合にのみ正しいです。 私はどちらを覚えていることはできませんが、CLRはPInvoke関数からの文字列戻り型がどちらか一方に割り当てられていると仮定します。

より確実な方法は、GetDirの戻り値をIntPtrにすることです。 その後、文字列型を取り出すためにMarshal.PtrToStringAnsi関数のいずれかを使用できます。 それはまたあなたが選択した方法で弦を解放する柔軟性をあなたに与えます。

[DllImport("your.dll", CharSet = CharSet.Ansi)]
IntPtr GetDir(StringBuilderパス);

GetDirの動作について、他に何かヒントがありますか。 入力文字列を変更しますか? 返される値はどのように割り当てられますか? あなたがそれを提供することができれば私はずっと良い答えを与えることができます。


12


やってみる

[DllImport("your.dll", CharSet = CharSet.Ansi)]
文字列GetDir(StringBuilderパス);

stringは自動的にゼロで終わる文字列に整列化され、CharSetプロパティを使って、UnicodeではなくANSIを使用するようMarshallerに指示します。 注:const char *にはstring(またはSystem.String)を使用し、char *にはStringBuilderを使用してください。

http://www.pinvoke.net/default.aspx/kernel32.GetShortPathName[この例]のように、MarshalAsを試すこともできます。