C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

const char*を返すDLL関数の呼び出し

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■95858 / inTopicNo.1)  const char*を返すDLL関数の呼び出し
  
□投稿者/ 平m (1回)-(2020/10/05(Mon) 11:49:34)

分類:[VB.NET/VB2005 以降] 

メーカーから提供されているDLLに付属のインクルードファイルで

const char* GetName(int index);

と、定義されている文字列型の関数を、VB.Netから呼び出すために、下記の様に定義し

<DllImport("xxxx.dll", EntryPoint:="GetName", SetLastError:=True,
CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function GetName() As String
End Function

呼び出した所、アプリがクラッシュ(例外コード: 0xc0000374が発生)したり
「'return value' をマーシャリングできません:無効なマネージ/アンマネージ型の組み合わせです。」
のようなエラーが発生します
色々と試して見ましたが、ダメでした。

試したこと
・関数の戻り型を、String, Byte(), IntPtr, StringBuilder などに変えた
・DllImportのCharSetを、Auto, UniCode などに変えた
・DllImport宣言を止めて、Declareで宣言した
Declare Function GetName Lib "xxxx.dll" () As <MarshalAsAttribute(UnmanagedType.LPStr)> String

const char*を返すようなDLL関数の呼び出し例をネットで検索して見ましたが
見つけられませんでした。

アドバイスをお願いいたします。

開発環境は、Windows10 Pro(x64) + VS(2019)のVB です。よろしくお願いします。

引用返信 編集キー/
■95859 / inTopicNo.2)  Re[1]: const char*を返すDLL関数の呼び出し
□投稿者/ 魔界の仮面弁士 (2854回)-(2020/10/05(Mon) 12:24:08)
No95858 (平m さん) に返信
> const char* GetName(int index);
> Public Shared Function GetName() As String

あれ、引数は?


> 色々と試して見ましたが、ダメでした。
ひとまず
 Function GetName(index As Integer) As IntPtr
にして、Marshal.PtrToString何某 で受け取れるか確認してみるとか。

https://social.msdn.microsoft.com/Forums/ja-JP/d2a8330f-9482-49f4-9ad2-b10326d6955c/char123641251012540124711251512522125311246412373124281242722411?forum=csharpgeneralja
引用返信 編集キー/
■95860 / inTopicNo.3)  Re[2]: const char*を返すDLL関数の呼び出し
□投稿者/ 774RR (831回)-(2020/10/05(Mon) 12:43:02)
DLL なのに _cdecl って本当なのか
char* の先の文字列のエンコーディングは何か
返される char* は DLL 内静的領域へのポインタなのか malloc 結果なのか CoTaskMemAlloc 結果なのか
あたりの情報が無いと妄想と憶測で pinvoke 書いてもメモリリークしてまともに動かないっス


引用返信 編集キー/
■95862 / inTopicNo.4)  Re[2]: const char*を返すDLL関数の呼び出し
□投稿者/ 平m (2回)-(2020/10/05(Mon) 13:04:47)
No95859 (魔界の仮面弁士 さん) に返信
>
> あれ、引数は?
>
>
>>色々と試して見ましたが、ダメでした。
> ひとまず
>  Function GetName(index As Integer) As IntPtr
> にして、Marshal.PtrToString何某 で受け取れるか確認してみるとか。
>

済みません。私の転記ミスです。
'index As Integer'の引数有りで試していました。

引用返信 編集キー/
■95863 / inTopicNo.5)  Re[3]: const char*を返すDLL関数の呼び出し
□投稿者/ 平m (3回)-(2020/10/05(Mon) 13:19:29)
No95860 (774RR さん) に返信

774RR さん。アドバイス有難うございます。

> DLL なのに _cdecl って本当なのか

この辺りはよく理解せずに、書いています。(サンプルに有った他の関数からのコピペです)
もう少し勉強して見ます。

> char* の先の文字列のエンコーディングは何か

CharSet:=CharSet.Ansiの指定は、間違いが無いと思います。
期待される文字列は、"Maker1"のような10文字未満の文字列で、同じDLLの、
他のStringを引数とする関数では、Ansiの指定で正常に受け渡しが出来ています。


> 返される char* は DLL 内静的領域へのポインタなのか malloc 結果なのか CoTaskMemAlloc 結果なのか
> あたりの情報が無いと妄想と憶測で pinvoke 書いてもメモリリークしてまともに動かないっス

これに関しては、全く情報は有りません。
いくつかのパターンで試して見て、希望する文字列が受け取れれば良しと、考えていたのですが、
そんなに簡単では無いという事ですね。


引用返信 編集キー/
■95864 / inTopicNo.6)  Re[3]: const char*を返すDLL関数の呼び出し
□投稿者/ 平m (4回)-(2020/10/05(Mon) 13:20:00)
No95862 (平m さん) に返信
> ■No95859 (魔界の仮面弁士 さん) に返信
>>
>>あれ、引数は?
>>
>>
> >>色々と試して見ましたが、ダメでした。
>>ひとまず
>> Function GetName(index As Integer) As IntPtr
>>にして、Marshal.PtrToString何某 で受け取れるか確認してみるとか。
>>
>
> 済みません。私の転記ミスです。
> 'index As Integer'の引数有りで試していました。
>
引用返信 編集キー/
■95865 / inTopicNo.7)  Re[4]: const char*を返すDLL関数の呼び出し
□投稿者/ 平m (5回)-(2020/10/05(Mon) 13:23:51)


済みません。
使い慣れておらず。ゴミを送信してしまいました。
先の投稿は、無視してください。
引用返信 編集キー/
■95866 / inTopicNo.8)  Re[2]: const char*を返すDLL関数の呼び出し
□投稿者/ 平m (7回)-(2020/10/05(Mon) 13:51:00)
No95859 (魔界の仮面弁士 さん) に返信

> ひとまず
>  Function GetName(index As Integer) As IntPtr
> にして、Marshal.PtrToString何某 で受け取れるか確認してみるとか。


関数の戻り値を、IntPtrにして、戻り値のポインターを引数にして Marshal.PtrToStringAnsi()
に渡した所、希望の文字列が受け取れました。


Dim bName As String = Marshal.PtrToStringAnsi( GetName(0) )


魔界の仮面弁士 さん有難うございました。


解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ