はじめまして。TOMOと申します。
C言語で作成されたDLL(D747F.DLL)をVBで使用したいと思うのですが、下記のような場合、どのように宣言すればいいかわかりません。ご教授願います。
BOOL DT_GetLog(DWORD Handle, ERRLOG *Log) ;
ERRLOGは構造体です。
型WORD 変数名 ErrorCount
型WORD 変数名 ErrorCode
以上、宜しくお願い致します。
つ[Declare]
Public declare function DT_GetLog Lib "D747F.DLL" (byval Hanlde as long,ByVal ERRLOGADD As LONG) As long
でOKかとおもいます。
構造体の内容取得はcopymemoryなどで。
VB6を前提にします。
BOOL((win32では)intのtypedef)
→ VBでは C言語の int型と同じサイズになる Long 型
※Boolean型ではない。
DWORD((win32では)unsinged longのtypedef)
→ VBでは C言語の unsinged long型と同じサイズになる Long型
ERRLOG *
→ VBでは C言語のポインタ型つまり void* 型と同じサイズになる Long型
よって
BOOL DT_GetLog(DWORD Handle, ERRLOG *Log) ;
は
Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByVal Log As Long) As Long
かな。
※Logはポインタですので、CopyMemory等のAPIでメモリをコピーする必要がある。
また、Logの指定のところはAnyでもいけたと思う。(じゃなきゃCopyMemoryって使えん罠)
Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByRef Log As Any) As Long
WORD((win32では)unsigned shortのtypedef)
→ VBでは C言語の unsigned short型と同じサイズになる Integer型
ERRLOG
→ sizeofでサイズを確認してVB側で Type を使ってください。
おそらく、
Private Type ERRLOG
ErrorCount As Integer
ErrorCode As Integer
End Type
で大丈夫かと思います。(ちゃんとLenB関数と、sizeofの結果が等しいことを確認すること)
というか、
>Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByVal Log As Long) As Long
は不味い気がしてきた。
DT_GetLog側でデータを格納する場合があるので、やはり
Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByRef Log As Any) As Long
か
Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByRef Log As ERRLOG) As Long
(ってのは出来たっけ?)
もしくは、Integer型配列とかを指定するんですかね。
ちっ、マルチヵょ
http://www2.moug.net/bbs/program/20061018000002.htm
Blueさまへ。
掲示板を使うのが始めてでルール等がわからなくて。。。
すみませんでした。
マルチでも他に見てる人も居るので終結させておかないと....
Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByRef Log As ERRLOG) As Long
これ完全にOKでしょう。
Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByRef Log As Any) As Long
これもOKですね。
Private Declare Function DT_GetLog Lib "D747F.DLL" (ByVal Handle As Long, ByRef ErrCount As Integer) As Long
としておいて
DT_GetLog(Handle, Log.ErrorCount)
とやるのもたぶんOKでしょう、要するのにユーザー定義型のアドレスが渡れば何でも。
CopyMemoryは多分必要無いと思われますが、文字列が含まれた場合の処理でしょうか?
試しに構造体に文字列を含めてやってみると、
C側は:
struct ERRLOG
{
char ErrorMeg[20];
WORD ErrorCount;
WORD ErrorCode;
};
D747F.DLL BOOL __stdcall DT_GetLog(DWORD Handle, ERRLOG *Log) {
strcpy(Log ->ErrorMeg ,"エラーが出ました。");
Log ->ErrorCount += (WORD)Handle;
Log ->ErrorCode += (WORD)Handle;
return true;
}
VB側は:
Private Declare Function DT_GetLog Lib "D747F.DLL" _
(ByVal handle As Long, ByRef Log As ERRLOG) As Long
Private Type ERRLOG
ErrorMsg As String * 20
ErrorCount As Integer
ErrorCode As Integer
End Type
Private Sub Command1_Click()
Dim ret As Long, Log As ERRLOG, handle As Long
Dim Meg As String
'handleをオフセット値として、Log.ErrorCountとLog.ErrorCodeを返す。
handle = 200: Log.ErrorCount = 1: Log.ErrorCode = 2
ret = DT_GetLog(handle, Log)
Msg = Left$(Log.ErrorMsg, InStr(Log.ErrorMsg, vbNullChar) - 1)
Debug.Print ret & ": " & Msg & ": " & Log.ErrorCount & ": " & Log.ErrorCode
End Sub
Cのコードはかなりいいかげんですが、受け渡しは、問題が無い気がします。
ありがとうございました。
エラーが出なくなりました。
あと、下記についてもご教授願います。(初心者ですみません。)
BOOL Board_Open(DWORD *Handle) ;
VB側は下記のようにしました。
Private Declare Function Board_Open Lib "D747F.DLL" _
(ByRef Handle As Long) As Long
Handleにはデバイスハンドルがはいるのですが、どのように値をとれば
良いですか?
以上、宜しくお願い致します。
実際C側で何が設定されるんでしょうか?
デバイスハンドルってことは HDC でしょうか?
もし HDC である場合、なんでそういう関数宣言(DWORD*)になっているんでしょうか?
それ以外である場合、Board_Openの中身を見てみないとどうなっているのかわからないので
一概にこうすればいいとか断定できません。
ハンドルと名がつけば、何を見なくてもLongですね。
ただし、DLLでハンドルの受け渡しには注意が必要です。
MSDNで「DLL」で検索して、
「DLL, DLL プロシージャに情報を渡す」->
「DLL にハンドルを使用」
を読んでみてください。
ありがとうございました。
全て解決致しました。
また、宜しくお願い致します。
ツイート | ![]() |