DLLでメモリエラー…

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
Pon骨

DLLでメモリエラー…

#1 投稿記事 by Pon骨 »

はじめまして。ちょっと前からActiveBasicを使ってます。
さっそくAB5にてDLLを作ってみようと試したのですが、呼び出し時にメモリエラーになってしまいます。

コード: 全て選択


Dim iniFileName(255) As String

Function Export OpenFile(ByVal fID As Integer, ByVal sFileName As BytePtr) As Integer
	If fID < 0 Or fID > 255 Then
		OpenFile = 1
	ElseIf iniFileName(fID) <> "" Then
		OpenFile = 2
	Else
		iniFileName(fID) = MakeStr(sFileName)
		OpenFile = 0
	End If
End Function
このようなコードで、呼び出しはVB6から行いました。

コード: 全て選択


Private Declare Function OpenFile Lib "test.dll" (ByVal fID As Integer, ByVal sFileName As String) As Integer

Private Sub Form_Load()
	Debug.Print OpenFile(0, App.Path & "\test.txt")
End Sub
MakeStrを無しにしてみたり、AB側のバグかなと思って4.24、4.23……4.20まで下げて試してみましたが全部同じメモリエラーが発生しました。
何がいけないのでしょうか、ご教授よろしくお願いします。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#2 投稿記事 by konisi »

VB6に関してはあまり詳しくはないのですが、VB側の第二引数がString型になっているので、それをByteptr型に直してみてください。
AB定義のString型とVB定義のString型に互換性がなければ、そこでエラーが起きている可能性があります。

・・・それと。
AB4xx系はAB413とAB420でシステムそのものが大きく変わっているので、AB424とAB423で変化を調べるより有効だと思います。
ただし、AB413では代入演算( += -=等)が使えなかった筈なので、移植する必要があると面倒ですが。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
Pon骨

#3 投稿記事 by Pon骨 »

>AB4xx系はAB413とAB420でシステムそのものが大きく変わっているので
AB4.13にて試しましたが同じエラーだったので、やはりコードのどこかに原因があるんだと思います。

>VB側の第二引数がString型になっているので、それをByteptr型に直してみてください
VBにBytePtr型は存在しません…
ABのBytePtrにVBからのStringを渡すことが出来ると認識していましたが、途中で仕様が変わったのでしょうか。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#4 投稿記事 by konisi »

BytePtr型は、基本的にByte型配列の先頭を指しています。
という事で、VBのString型をByte型の配列に代入して、(出来るかどうかはわからんが。)その配列の先頭をBytePtr型だと言えばいいかと思います。

ABでの方法

コード: 全て選択

Sub Form_Load()
    Dim A$ As String,B As DWord
    A$=MakeStr(App.path)+"\test.txt"
    B=calloc(Len(A$)+1)
	memcpy(B,A$,Len(A$))
#ifdef _DEBUG
	    MessageBox(0,Str$(OpenFile(0,B)),"debug",MB_OK)
#endif
	free(B)
End Sub 
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#5 投稿記事 by イグトランス »

いいえ,VBのDeclareでString型を値渡し(ByVal)にすると,呼出時にその引数はANSI文字列へ変換されます。
ようするにABのBytePtrで受け取って全く問題ないはずです。
なお私はVBを持っておらず,VBAで代用しています。(Excel 2003 VBA:VBのバージョンは6.0相当です)

そのVBAでもやはりPon骨さんのコードで落ちることは確認しました。
これからしばらく原因を探ってみたいと思います。
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#6 投稿記事 by イグトランス »

AB5のDLLデバッグを利用したところ,iniFileNameが初期化されていないことが原因だとわかりました。

そこで,次の関数を追加し,

コード: 全て選択

Sub InitializeIniFileName()
	Dim i As SIZE_T
	For i = 0 To 255 'Len (iniFileName)
		iniFileName(i) = ""
	Next
End Sub
DllMainがDLL_PROCESS_ATTACHで呼び出されたときにInitializeIniFileName()を呼んでやるようにしたところ,

コード: 全て選択

Function Export DllMain(hinstDLL As HINSTANCE, fdwReason As DWord, pvReserved As VoidPtr) As BOOL
	'DLLエントリポイント
	Select Case fdwReason
		Case DLL_PROCESS_ATTACH
			'DLLがプロセス空間にロードされた時に実行されます。
			_System_StartupProgram()
			InitializeIniFileName()
			DllMain = TRUE
	End Select
End Function
AB5では正常に実行できるようになりました。
AB4では試していませんが,おそらく同様になると思います。

これはABのバグでしょう。それに対する回避策だと思ってください。
Pon骨

#7 投稿記事 by Pon骨 »

動くようになりました。ありがとうございます。
返信する