最近VB2008を始めました。
それまではVB6を使用してきました。
VB6側で
Type TThLog
Qso(3927) As Byte
End Type
Declare Function Vdbf_rcount Lib "Thdll2Vb.dll" (d As TThLog) As Long
これをVB2008側での一部のコードですが下記のようにしています。
Marshal 関係が分からずにエラーが出ていますが記述のアドバイスをいただけたらと思います。
Web検索などもしていますが難解で苦労しています。
Structure TThLog
<VBFixedArray(3927)> Dim Qso() As Byte
Public Sub Initialize()
ReDim Qso(3927)
End Sub
End Structure
<DllImport("Thdll2Vb.dll")> _
Private Shared Function Vdbf_rcount(<MarshalAs(UnmanagedType.LPTStr)> ByRef d As TThLog) As Integer
End Function
recno = Vdbf_rcount(log)
> VB6側で
> Type TThLog
> Declare Function Vdbf_rcount Lib "Thdll2Vb.dll" (d As TThLog) As Long
引数は構造体の参照渡し、戻り値は 32bit 整数型、ですね。
> これをVB2008側での一部のコードですが下記のようにしています。
構造体に拘らないのであれば、
Private Declare Function Vdbf_rcount Lib "Thdll2Vb" (ByRef qso As Byte) As Integer
にして、
Dim log(3927) As Byte
recno = Vdbf_rcount(log(0))
でいけるかも。
構造体で実装するなら、
<StructLayout(LayoutKind.Seqential, Pack:=1)> Structure TThLog
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=3928)>Public QSo() As Byte
End Sub
Private Declare Function Vdbf_rcount Lib "Thdll2Vb" (ByRef qso As TThLog) As Integer
にして、
Dim d As TThLog
ReDim d.Qso(3927)
recno = Vdbf_rcount(d)
とか。
# どちらも未確認。
魔界の仮面弁士さん、ありがとうございます。
下記のようにして見ましたがファイルオープン時に
sdの返値が5になり失敗しているようです。 ゼロで成功。
sd = Vdbf_open("C:\HAMLOG\Hamlog.hdb", d)
お気づきの箇所があればご指摘いただければ幸いです。
Imports System
Imports System.Text
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class Form1
<StructLayout(LayoutKind.Sequential, Pack:=1)> Structure TThLog
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=3928)> Public QSo() As Byte
End Structure
Private Declare Function Vdbf_rcount Lib "Thdll2Vb.dll" (ByRef qso As TThLog) As Integer
<DllImport("Thdll2Vb.dll")> _
Private Shared Function Vdbf_open(ByRef s As String, ByRef d As TThLog) As Integer
End Function
<DllImport("Thdll2Vb.dll")> _
Private Shared Sub Vdbf_close(ByRef d As TThLog)
End Sub
Public Th As TDBFh
Dim d As TThLog
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim sd As Integer
Dim recno As Integer
ReDim d.QSo(3927)
sd = Vdbf_open("C:\HAMLOG\Hamlog.hdb", d)
recno = Vdbf_rcount(d)
Vdbf_close(d)
Label2.Text = recno
End Sub
End Class
Declare 構文と DllImport 構文が混じっているのが気になりますが、それはさておき。
> <DllImport("Thdll2Vb.dll")> _
> Private Shared Function Vdbf_open(ByRef s As String, ByRef d As TThLog) As Integer
> End Function
この部分があやしいです。この部分、本当に正しい宣言になっていますか?
String 型を DLL に ByRef で渡すのは、かなり特殊な状況に限られますよ。
Thdll2Vb.dll というのは、Windows や VB に標準で用意された物ではありませんし、
質問文には、VB2008 との比較対象となる VB6 当時のコードが無いので、
答えにくいのですが、DLL 名で検索してみると、下記の Th505API.lzh がヒットしました。
http://hamlog.no.coocan.jp/mou/
今回問題にしているのが、この DLL の事であるのかどうかは分かりませんが、
これを見ると、Vdbf_open というのは、
> int WINAPI __export Vdbf_open(const char *fname, TThLog *th)
であり、かつ、VB6 から利用する場合には
> Declare Function Vdbf_open Lib "Thdll2Vb.dll" (ByVal s As String, d As TThLog) As Long
であると記載があります。
という事は、VB.NET からの利用は
Private Declare Function Vdbf_open Lib "Thdll2Vb" (ByVal s As String, ByRef d As TThLog) As Integer
もしくは、
Private Declare Ansi Function Vdbf_open Lib "Thdll2Vb" (ByVal s As String, ByRef d As TThLog) As Integer
になるかと思います。(未確認)
魔界の仮面弁士 さん、ありがとうございました。
>今回問題にしているのが、この DLL の事であるのかどうかは分かりませんが、
はい、そのDLLです。
ご指摘の件などを踏まえて修正したところ ファイルオープン、
レコード件数の取得も出来るようになりました。
ツイート | ![]() |