始めまして、ゆうと申します。
早速ですが、
VB6で開発を行っているのですが。
質問は、Delphiで確保されている大きさとVBで宣言した大きさが
違うのではないかと思っています。
そこで、DelphiとVBの宣言の型の違いで、VBでどのように宣言すれば
良いのでしょうか?
DLLにもよると思いますが、何かヒントになる事があればよろしくお願い致します。
(Delphiで作成されたDLLをVBで使用したいのですが、
実行時すると、アプリケーションエラー(メモリ)なり
なかなか,うまく行きません。)
Delphi製のDLLをVBで使ったことは一度だけあります。
(MMLのMIDI変換に、dSakura.dllを)
特に問題は起こらなかったですけど…。
(文字列引数も入ってました)
どういうDLLですか?自作だとしたら、
DLLがわでPCharを使ってないとかいうことも考えられます。
DLLで他のソフトでも使う関数を作るときは、
文字列はPCharでないといけないはずです。
(DLL作成時"Borland製DLLをともに使えばだいじょうぶ"というコメントが出ますけど、
別に"他の言語のソフトで使ってもだいじょうぶ"とは一言もいっていないわけで…)
DLLの問題でなかったら、あんまり問題というのは思いつきません。
普通のAPIを呼び出すのと同じように、やればいいと思います。
Array Of Char,PChar=String(固定長文字列) Integer,Cardinal,Pointer=Long
他は多分ないと思います。recordと書いてあったら、それは構造体のことです。
DelphiはVBよりデータ型が多い(VBはデータ型が少ない、だっけ^^;)といわれますけど、
汎用型だけを数えると、VBよりむしろデータ型は少ないです。
まあ、ポインタが数値と別々にされてるくらいで。
そう言えばほとんど"文字列"と"数値"で事足りちゃいますねぇ、
HSPにはデータ型が"文字列型"と"数値型"しかない(小数はサポートされていない)と聞きますけど、
それでほとんど充分なんですねぇ。
・Delphi側で「stdcall」宣言をしていない。
・VB側のAPI宣言でByValとByRefの宣言が間違っている。
・VB側のAPI宣言(引数の数など)が間違っている。
などのことも考えられます。
>そこで、DelphiとVBの宣言の型の違いで、VBでどのように宣言すれば
>良いのでしょうか?
そのコードを記述してくれないと分かりません。(もしくは入手先URL)
そうそう、VBでの宣言が分からないAPI関数(DLLの中の関数)の宣言で、
一番困るのが、値を渡すか参照を渡すかですねぇ…。
でも、これを間違えるとたしかVBが強制終了したような…。
基本的には"結果を受け取るためのバッファ"みたいなことが書いてないものには、
値渡しでいいと思いますけど…。
自作の場合、varで宣言した(またはなにもつけなかった)引数以外は、値渡しかもしれません。
自作DLLをVBから使ったことも、文字列を返したこともないので、よく分かりませんけど…^^;
みなさま!
本当に、ありがとうございます。
質問の内容があまりにもグローバルすぎたようですので、
詳細を書かせていただきます。
実は、図書館のソフトの開発をしているのですが、
TRCDと言う、CD−ROMで発売されている図書情報を
直接取り込みたいと思っています。
DLLは提供を受けたのですが、Delphiで作成していますとの事です。
流れとしては、
1.CD−OPEN
2.キーで検索
3.ヒットした場合、MARCbuffへ格納
4.その結果を元に、ITEMを指定して一部を取出す。
3までで、MARCbuffへそれらしき情報は格納されてますが
その先がうまく行きません。
以下が、簡単なI/Oのソースです。
************************************
Option Explicit
''TRCD検索用エリア
Private TRCD_DEV As String
Private TRCD_Gno As Long
Private TRCRErrMsg As String
'----------------------------------------------------------------------------------
' TRCD DLL Function Module
'----------------------------------------------------------------------------------
'' TRCD_RETの検索種別コード
Private Const EKTI = 1 ''書名全文
Private Const ATI = 2 ''書名分かち
Private Const EKAU = 3 ''著者前方一致
Private Const AAU = 4 ''著者分かち
Private Const SP = 5 ''出版者
Private Const EKKW = 6 ''件名全文
Private Const KW = 7 ''件名分かち
Private Const NDC8 = 8 ''NDC8版
Private Const NDC9 = 17 ''NDC9版 (#)
Private Const DISBN = 9 ''ISBNコード
Private Const CNO = 10 ''マークNo(JLA-No.)
Private Const PYEAR = 13 ''出版年
Private Const BRAU = 14 ''著者参照
Private Const BRSP = 15 ''出版者参照
Private Const BRKW = 16 ''件名参照
'' Condcd (論理演算子)
Private Const cAND = 1 ''論理積
Private Const cOR = 2 ''論理和
Private Const cClear = 3 ''Gnoのクリア
'****TRCD.DLL 構造体定義****
Private Type cdinf
EDITION As Integer
CCDATE As String * 8
SDATE As String * 8
EDATE As String * 8
VOLNAME As String * 128
End Type
'****参照検索結果****
Private Type blist
Brow As String * 80
Btno As String * 11
End Type
'****書名一覧リスト****
Private Type Tilist
CNO As String * 15
Title As String * 30
Author As String * 14
Pub As String * 10
End Type
'****項目識別子****
Private Type Tagset
tagno As String * 3
Subf As String * 1
seq As Integer
End Type
'' Function
Private Declare Function TRCD_OPEN Lib "trcd.dll" _
(ByVal dev As String, ByRef pcdinf As cdinf) As Integer
Private Declare Function TRCD_CLOSE Lib "trcd.dll" _
(ByVal dev As String) As Integer
''検索
Private Declare Function TRCD_RET Lib "trcd.dll" _
(ByVal dev As String, ByVal KeyString As String, ByVal ccond As Integer, ByRef Gno As Long) As Long
''集合検索
Private Declare Function TRCD_BRO Lib "trcd.dll" _
(ByVal dev As String, ByVal KeyString As String, pblist As blist) As Integer
''検索結果の取得
Private Declare Function TRCD_LIST Lib "trcd.dll" _
(ByVal Gno As Integer, ByVal Gindex As Long, ByVal lsize As Long, ByRef tIlits As Tilist) As Integer
''マーク検索
Private Declare Function TRCD_MARC Lib "trcd.dll" _
(ByVal Gno As Integer, ByVal Mindex As Integer, ByVal buffer As String) As Integer
''マーク編集
Private Declare Function TRCD_MARC_EDIT Lib "trcd.dll" _
(ByVal buffer As String, ByVal MARC_REC As String, ByRef D_type As Integer, ByVal Local_L As String, ByVal L_NUM As Long) As Long
''項目要素の取出
Private Declare Function TRCD_MARC_ITEM Lib "trcd.dll" _
(ByVal buffer As String, ByRef tag As Tagset, ByVal dat As String) As Integer
'Dim MARCbuff(1024000) As Byte
Dim MARCItem As String
Private Sub Form_Load()
TRCD_DEV = "F:" 'CD-Drive
Call RUN
' Unload Me
End Sub
Private Sub RUN()
Dim In_Text As String
Dim Result As Long
Dim pcdinf As cdinf
Dim KeyString As String
Dim ptilist As Tilist
Dim buf_size As Integer
Dim MARCbuff As String
Dim tg As Tagset
Dim Marc_size As Integer
Dim MARCItem As String
TRCRErrMsg = ""
'Open
Result = TRCD_OPEN(TRCD_DEV, pcdinf)
''ISBNコード検索
In_Text = InputBox("例:4-901164-05-8", "ISBN", "4-947676-50-7")
KeyString = Trim(Str(DISBN)) + ":" + In_Text
Result = TRCD_RET(TRCD_DEV, KeyString, cClear, TRCD_Gno)
If Result > 0 Then
MARCbuff = String(65562, vbNullChar)
buf_size = TRCD_MARC(TRCD_Gno, 1, MARCbuff)
'' 項目データの読込(書名)
tg.tagno = "251"
tg.Subf = "A"
tg.seq = 1
MARCItem = String(12282, vbNullChar)
Marc_size = TRCD_MARC_ITEM(MARCbuff, tg, MARCItem)
TRCD_CLOSE (TRCD_DEV)
'**** 内容確認 ****
Open "file.txt" For Output As #1
Print #1, "MARCbuff->" & MARCbuff
Print #1, "tgano = " & tg.tagno
Print #1, "Sbuf = " & tg.Subf
Print #1, "seq = " & tg.seq
Print #1, "MARCItem->" & MARCItem
Close #1
' Call Shell("D:\MEGASOFT\MIW\MIW.EXE file.txt", vbNormalNoFocus)
Exit Sub
End If
''検索データが存在しないか、またはエラー(マイナス値)詳細はDLL使用を参照
' TrcdFindFirst = 0
TRCD_CLOSE (TRCD_DEV)
TRCRErrMsg = "該当データがありません。"
End Sub
**********************************
みなさまありがとうございます。
質問があまりにもグローバルすぎるため何をいっているのかわかりませんよね。
実は、図書館ソフトをVBで開発しておりまして、
TRCDという、本の情報が登録されたCDが発売されていまして、
そのCDを直接アクセスする方法として DLLの提供を受けました。
そのDLLがDelphiで記述してあるとの事です。
流れは、
1.オープン
2.ISBNというコードで検索
3.ヒットした場合、MARCbuffへ格納。
4.その中からITEMを指定して、一部を取出す。
5.クローズ
3の段階で、MARCbuffへそれらしき情報ははいっているようですが
その後が続きません。
以下が簡単に作成したI/Oのソースです。
*************************************************
option Explicit
''TRCD検索用エリア
Private TRCD_DEV As String
Private TRCD_Gno As Long
Private TRCRErrMsg As String
'----------------------------------------------------------------------------------
' TRCD DLL Function Module
'----------------------------------------------------------------------------------
'' TRCD_RETの検索種別コード
Private Const EKTI = 1 ''書名全文
Private Const ATI = 2 ''書名分かち
Private Const EKAU = 3 ''著者前方一致
Private Const AAU = 4 ''著者分かち
Private Const SP = 5 ''出版者
Private Const EKKW = 6 ''件名全文
Private Const KW = 7 ''件名分かち
Private Const NDC8 = 8 ''NDC8版
Private Const NDC9 = 17 ''NDC9版 (#)
Private Const DISBN = 9 ''ISBNコード
Private Const CNO = 10 ''マークNo(JLA-No.)
Private Const PYEAR = 13 ''出版年
Private Const BRAU = 14 ''著者参照
Private Const BRSP = 15 ''出版者参照
Private Const BRKW = 16 ''件名参照
'' Condcd (論理演算子)
Private Const cAND = 1 ''論理積
Private Const cOR = 2 ''論理和
Private Const cClear = 3 ''Gnoのクリア
'****TRCD.DLL 構造体定義****
Private Type cdinf
EDITION As Integer
CCDATE As String * 8
SDATE As String * 8
EDATE As String * 8
VOLNAME As String * 128
End Type
'****参照検索結果****
Private Type blist
Brow As String * 80
Btno As String * 11
End Type
'****書名一覧リスト****
Private Type Tilist
CNO As String * 15
Title As String * 30
Author As String * 14
Pub As String * 10
End Type
'****項目識別子****
Private Type Tagset
tagno As String * 3
Subf As String * 1
seq As Integer
End Type
'' Function
Private Declare Function TRCD_OPEN Lib "trcd.dll" _
(ByVal dev As String, ByRef pcdinf As cdinf) As Integer
Private Declare Function TRCD_CLOSE Lib "trcd.dll" _
(ByVal dev As String) As Integer
''検索
Private Declare Function TRCD_RET Lib "trcd.dll" _
(ByVal dev As String, ByVal KeyString As String, ByVal ccond As Integer, ByRef Gno As Long) As Long
''集合検索
Private Declare Function TRCD_BRO Lib "trcd.dll" _
(ByVal dev As String, ByVal KeyString As String, pblist As blist) As Integer
''検索結果の取得
Private Declare Function TRCD_LIST Lib "trcd.dll" _
(ByVal Gno As Integer, ByVal Gindex As Long, ByVal lsize As Long, ByRef tIlits As Tilist) As Integer
''マーク検索
Private Declare Function TRCD_MARC Lib "trcd.dll" _
(ByVal Gno As Integer, ByVal Mindex As Integer, ByVal buffer As String) As Integer
''マーク編集
Private Declare Function TRCD_MARC_EDIT Lib "trcd.dll" _
(ByVal buffer As String, ByVal MARC_REC As String, ByRef D_type As Integer, ByVal Local_L As String, ByVal L_NUM As Long) As Long
''項目要素の取出
Private Declare Function TRCD_MARC_ITEM Lib "trcd.dll" _
(ByVal buffer As String, ByRef tag As Tagset, ByVal dat As String) As Integer
'Dim MARCbuff(1024000) As Byte
Dim MARCItem As String
Private Sub Form_Load()
TRCD_DEV = "F:" 'CD-Drive
Call RUN
' Unload Me
End Sub
Private Sub RUN()
Dim In_Text As String
Dim Result As Long
Dim pcdinf As cdinf
Dim KeyString As String
Dim ptilist As Tilist
Dim buf_size As Integer
Dim MARCbuff As String
Dim tg As Tagset
Dim Marc_size As Integer
Dim MARCItem As String
TRCRErrMsg = ""
'Open
Result = TRCD_OPEN(TRCD_DEV, pcdinf)
''ISBNコード検索
In_Text = InputBox("例:4-901164-05-8", "ISBN", "4-947676-50-7")
KeyString = Trim(Str(DISBN)) + ":" + In_Text
Result = TRCD_RET(TRCD_DEV, KeyString, cClear, TRCD_Gno)
If Result > 0 Then
MARCbuff = String(65562, vbNullChar)
buf_size = TRCD_MARC(TRCD_Gno, 1, MARCbuff)
'' 項目データの読込(書名)
tg.tagno = "251"
tg.Subf = "A"
tg.seq = 1
MARCItem = String(12282, vbNullChar)
Marc_size = TRCD_MARC_ITEM(MARCbuff, tg, MARCItem)
TRCD_CLOSE (TRCD_DEV)
'**** 内容確認 ****
Open "file.txt" For Output As #1
Print #1, "MARCbuff->" & MARCbuff
Print #1, "tgano = " & tg.tagno
Print #1, "Sbuf = " & tg.Subf
Print #1, "seq = " & tg.seq
Print #1, "MARCItem->" & MARCItem
Close #1
' Call Shell("D:\MEGASOFT\MIW\MIW.EXE file.txt", vbNormalNoFocus)
Exit Sub
End If
''検索データが存在しないか、またはエラー(マイナス値)詳細はDLL使用を参照
' TrcdFindFirst = 0
TRCD_CLOSE (TRCD_DEV)
TRCRErrMsg = "該当データがありません。"
End Sub
*************************************************
※Delphiで宣言しているサンプルだそうです。
*************************************************
unit UCDDLL_DEF;
{ TRCD DLL データ構造定義}
interface
uses windows;
type
did = array[1..8] of char;
vid = array[1..4] of char;
nam = array[1..128] of char;
Tdate = array[1..8] of char;
{TRCD 概要記述}
ptCD_Info = ^tCD_Info;
tCD_Info = packed record
Edition : WORD;
CDATE : Tdate;
STDATE : Tdate;
EDDATE : Tdate;
VOLNAME : nam;
end;
const
{EDITION,TRCD_OPEN(Error) constant}
cdBasic1 : WORD = 1; //基本版1
cdBasic2 : WORD = 2; //基本版2
cdBasic3 : WORD = 3; //基本版3
cdMeiTai : WORD = 4; //明治・大正期版
cdCurrent : WORD = 5; //カレント版
cdJunior : WORD = 6; //TRCD ジュニア
cdError : WORD = 9; //TRCD以外のCD
cdDblErr : WORD = 10; //二重オープンエラー
cdNotReady: WORD = 11; //CD_ROM ドライブにCDが用意されていない
{TRCD_CLOSE(Error) constant}
cdCloseE : WORD = 1; //TRCD_CLOSEに失敗した。
const
{検索項目}
EKTI : WORD = 1; //書名全文
ATI : WORD = 2; //書名分かち
EKAU : WORD = 3; //著者名前方一致
AAU : WORD = 4; //著者名分かち
SP : WORD = 5; //出版社
EKKW : WORD = 6; //件名
KW : WORD = 7; //件名分かち
NDC8 : WORD = 8; //NDC8版
NDC9 : WORD = 17; //NDC9版
ISBN : WORD = 9; //ISBN
CNO : WORD = 10; //JLA_NO
PYEAR : WORD = 13; //出版年
BRAU : WORD = 14; //著者参照
BRSP : WORD = 15; //出版社参照
BRKW : WORD = 16; //件名参照
const
{検索論理演算子}
cAND : WORD = 1;
cOR : WORD = 2;
cClear: WORD = 3;
{RET_KEY error results}
PathErr : DWORD = -1;
InameErr : DWORD = -2;
PyearErr : DWORD = -3;
PYOfferr : DWORD = -4;
LikeErr : DWORD = -5; //この項目では前方一致は指定できない
NotKeyErr: DWORD = -6; //キーが一つも入っていない。(もしくは出版年のみ)
OverErr : DWORD = -7; //検索結果のサイズが2Mバイトを超えた
KCharErr : DWORD = -8; //漢字キーが認められていない検索項目で、漢字が入力
type
{一覧リスト}
ptTlist = ^tTlist;
tTlist = packed record
CNO : array [0..14] of char;
Title : array[0..29] of char;
Author : array[0..13] of char;
pub : array [0..9] of char;
end;
{一覧リスト取り出しのための配列}
ptarTlist = ^tarTlist;
tarTlist = array[1..200] of tTlist;
{参照リスト}
ptBlist = ^tBlist;
tBlist = packed record
brow : array [0..79] of Char;
bno : array [0..10] of Char;
end;
{参照リスト取り出しのための配列}
ptarBlist = ^tarBlist;
tarBlist = array[1..2800] of tBlist; //1024バイト*64/91バイト=約720件
//2Mチェック変更にともない、
//[(1024*1024*2)/8] / 91バイト=約2800件
//に変更しました。
//
ptTagset = ^tTagSet;
tTagset = packed record
TagNo :array[0..2] of char;
Subf :char;
seq :Word;
end;
ptBuffer = ^tBuffer; // marc record buffer
tbuffer = array [0..12280] of char;
ptMbuffer = ^tMbuffer;
tMbuffer = array [0..65560] of char;
// MARC TYPE Define
const
UtypeCond = 0;
UtypeCDD = 1;
UtypeCDW = 2;
implementation
end.
***********************************
>質問は、Delphiで確保されている大きさとVBで宣言した大きさが
>違うのではないかと思っています。
データ型の大きさは同じサイズ(2,4byte)ですが、
符号付き整数と符号なし整数とで違いがあります。
Delphi定義
WORD (0〜65535) 2byte
DWORD (0〜4294967296) 4byte
VB定義
Integer (-32768〜32767) 2byte
Long (-2147483648〜2147483647) 4byte
>そこで、DelphiとVBの宣言の型の違いで、VBでどのように宣言すれば
>良いのでしょうか?
やっぱり、これかな?
WORD ->Integer
DWORD ->Long
※DLLによっては変更したほうが良い場合もあります。
>3の段階で、MARCbuffへそれらしき情報ははいっているようですが
>その後が続きません。
API宣言の「Delphiコード」がないと一概に答えられません。
が、たぶん、「参照渡し」が失敗していると思われます。
>以下が、簡単なI/Oのソースです。
大元のDelphiソース,間違っていると思います(^^;
> PathErr : DWORD = -1;
> InameErr : DWORD = -2;
> PyearErr : DWORD = -3;
> PYOfferr : DWORD = -4;
> LikeErr : DWORD = -5; //この項目では前方一致は指定できない
> NotKeyErr: DWORD = -6; //キーが一つも入っていない。(もしくは出版年のみ)
> OverErr : DWORD = -7; //検索結果のサイズが2Mバイトを超えた
> KCharErr : DWORD = -8; //漢字キーが認められていない検索項目で、漢字が入力
値の範囲が「0〜4294967296」なのに「マイナス」が入っています。
まあ、やりようにやればうまくできますが・・・。
最後に一言
・DelphiがVBで定義された文字配列(String)を「参照渡し」でうまく扱えるのか?
・構造体のポインタ渡しはVBとDelphiで互換性があるのか?
などが、疑問になります。
数々の回答ありがとうございました。
まだまだ、勉強不足ですね。
的確な質問が出来るように、も〜っと勉強してきます。
ゆうさん、うまくいきましたか?
私も今同じ図書館のTRCDの開発をしています。
同じところで詰まっています。
TRCD_MARC_ITEMのところがうまくいきません。
もしうまくいっているのでしたら、詳細を教えていただけませんか?
よろしくお願いします。
ツイート | ![]() |