Delphiで作成されたDLLをVBで使用でエラー!

解決


ゆう  2002-06-12 20:58:21  No: 75738

始めまして、ゆうと申します。

早速ですが、
VB6で開発を行っているのですが。

質問は、Delphiで確保されている大きさとVBで宣言した大きさが
違うのではないかと思っています。
そこで、DelphiとVBの宣言の型の違いで、VBでどのように宣言すれば
良いのでしょうか?

DLLにもよると思いますが、何かヒントになる事があればよろしくお願い致します。

(Delphiで作成されたDLLをVBで使用したいのですが、
実行時すると、アプリケーションエラー(メモリ)なり
なかなか,うまく行きません。)


たかみちえ  URL  2002-06-13 05:50:08  No: 75739

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にはデータ型が"文字列型"と"数値型"しかない(小数はサポートされていない)と聞きますけど、
それでほとんど充分なんですねぇ。


バティとジダンが・・・しくしく。  2002-06-13 06:11:57  No: 75740

・Delphi側で「stdcall」宣言をしていない。
・VB側のAPI宣言でByValとByRefの宣言が間違っている。
・VB側のAPI宣言(引数の数など)が間違っている。
などのことも考えられます。

>そこで、DelphiとVBの宣言の型の違いで、VBでどのように宣言すれば
>良いのでしょうか?

そのコードを記述してくれないと分かりません。(もしくは入手先URL)


たかみちえ  URL  2002-06-13 08:50:16  No: 75741

そうそう、VBでの宣言が分からないAPI関数(DLLの中の関数)の宣言で、
一番困るのが、値を渡すか参照を渡すかですねぇ…。

  でも、これを間違えるとたしかVBが強制終了したような…。

  基本的には"結果を受け取るためのバッファ"みたいなことが書いてないものには、
値渡しでいいと思いますけど…。

  自作の場合、varで宣言した(またはなにもつけなかった)引数以外は、値渡しかもしれません。
自作DLLをVBから使ったことも、文字列を返したこともないので、よく分かりませんけど…^^;


ゆう  2002-06-13 21:55:58  No: 75742

みなさま!
本当に、ありがとうございます。
質問の内容があまりにもグローバルすぎたようですので、
詳細を書かせていただきます。

実は、図書館のソフトの開発をしているのですが、
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
**********************************


ゆう  2002-06-13 22:06:34  No: 75743

みなさまありがとうございます。

質問があまりにもグローバルすぎるため何をいっているのかわかりませんよね。

実は、図書館ソフトを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.
***********************************


さすが、デル・ピエロ  2002-06-14 09:59:40  No: 75744

>質問は、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で互換性があるのか?
などが、疑問になります。


ゆう  2002-06-25 08:49:17  No: 75745

数々の回答ありがとうございました。
まだまだ、勉強不足ですね。
的確な質問が出来るように、も〜っと勉強してきます。


あいり  2002-09-14 22:56:43  No: 75746

ゆうさん、うまくいきましたか?
私も今同じ図書館のTRCDの開発をしています。
同じところで詰まっています。
TRCD_MARC_ITEMのところがうまくいきません。
もしうまくいっているのでしたら、詳細を教えていただけませんか?
よろしくお願いします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加