投稿者:しばっち
投稿日:2019年 9月 8日(日)19時10分42秒
|
|
|
十進BASIC上から64ビットDLL(x64)を呼び出したいので、Windows版十進BASIC(win64版)を
(テスト版、ベータ版でも)出して欲しいのですが、無理でしょうか?
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月 9日(月)09時11分34秒
|
|
|
> No.4711[元記事へ]
BASICAccは64ビットで使えばASSIGN文で64ビットDLLが使えます。
WIN64だと80ビットの拡張精度実数が使えないので,Windows64ビット版を作ると数値の精度は13桁になります(MACとLinuxの64ビットは拡張精度実数が使えるので数値の精度は15桁です)。
汎用版のVer.0.7.0.4をWIN64をターゲットにコンパイルして実行することができるので,それにVER.8のExtDLLユニットとBASICAccのWindows64ビットDLL呼び出し手順を組み合わせれば64ビットDLL呼び出し可能なものは作れますが,存在意義が乏しいように思います。
https://ja.osdn.net/projects/decimalbasic/releases/p13818
|
|
|
投稿者:しばっち
投稿日:2019年 9月10日(火)21時44分59秒
|
|
|
SHIRAISHI Kazuoさんへのお返事です。
> BASICAccは64ビットで使えばASSIGN文で64ビットDLLが使えます。
>
> WIN64だと80ビットの拡張精度実数が使えないので,Windows64ビット版を作ると数値の精度は13桁になります(MACとLinuxの64ビットは拡張精度実数が使えるので数値の精度は15桁です)。
> 汎用版のVer.0.7.0.4をWIN64をターゲットにコンパイルして実行することができるので,それにVER.8のExtDLLユニットとBASICAccのWindows64ビットDLL呼び出し手順を組み合わせれば64ビットDLL呼び出し可能なものは作れますが,存在意義が乏しいように思います。
まずBASICAcc1202についてですが、fpc path C:\Lazarus\fpc\3.0.4\bin\i386-win32
にLazarusをインストールして32ビットでコンパイルしました。
こちらの環境ではDLL(x86)呼び出しを行うものは全く動きません。
extype -9900エラーが出てまともに動きません。
DLL呼び出しをしないものは問題ありません。
BASIC8013Ja_Winもこちらの環境で試した結果
DLL呼び出しを行うものは全く動きません。
問題発生で動作停止します。
DLL呼び出しをしないものは問題ありません。
但し、Windows版BASIC7854ではこれらは問題なく動きます。
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月11日(水)08時31分5秒
|
|
|
> No.4714[元記事へ]
次のプログラムが,BASICAcc 1.2.0.2で動作します。
32ビット(Lazarus2.0.4 Win32版)
64ビット(Lazarus2.0.4 Win64版)
どちらでも動作します。
ANSI$関数は未公開かもしれませんが,suppliedsユニットで定義されています。
(BASICAccは内部文字コードがUTF-8なので,日本語はANSI$を噛まさないと文字化けします。)
FOR I=1 TO 3
SELECT CASE MESSAGEBOX(ANSI$("よろしいですか ")&STR$(I))
CASE 1
PRINT "OK"
CASE 2
PRINT "CANCEL"
END SELECT
NEXT I
END
EXTERNAL FUNCTION MESSAGEBOX(M$)
!flagの値
LET MB_OK=00000000 ![OK]
LET MB_OKCANCEL=00000001 ![OK][キャンセル]
LET MB_ABORTRETRYIGNORE=00000002 ![中止][再試行][無視]
LET MB_YESNOCANCEL=00000003 ![はい][いいえ][キャンセル]
LET MB_YESNO=00000004 ![はい][いいえ]
LET MB_RETRYCANCEL=00000005 ![再試行][キャンセル]
!定数名 値 ボタンの種類
!IDOK= 1 !OK
!IDCANCEL= 2 !キャンセル
!IDABORT= 3 !中止
!IDRETRY= 4 !再試行
!IDIGNORE= 5 !無視
!IDYES= 6 !はい
!IDNO= 7 !いいえ
!定数名 値 アイコンの種類
LET MB_ICONSTOP=16 !0x00000010 停止のアイコン
LET MB_ICONQUESTION=32 !0x00000020 疑問符のアイコン
LET MB_ICONEXCLAMATION=48 !0x00000030 感嘆符のアイコン
LET MB_ICONINFORMATION=64 !0x00000040 吹き出しに「i」のアイコン
LET MESSAGEBOX=MESSBOX(0,M$,"BASIC",BITOR(MB_OKCANCEL,MB_ICONEXCLAMATION))
END FUNCTION
EXTERNAL FUNCTION MESSBOX(OWNER,TEXT$,CAPTION$,FLAG)
ASSIGN "user32.dll","MessageBoxA",GUI
END FUNCTION
http://hp.vector.co.jp/authors/VA008683/
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月11日(水)08時52分29秒
|
|
|
> No.4714[元記事へ]
Windows版BASIC 8.0.1.7だと次のプログラムで動作します。ただし,32ビットです。
(ASSIGN文に,GUIオプションは書けない。)
FOR I=1 TO 3
SELECT CASE MESSAGEBOX(ANSI$("よろしいですか ")&STR$(I))
CASE 1
PRINT "OK"
CASE 2
PRINT "CANCEL"
END SELECT
NEXT I
END
EXTERNAL FUNCTION MESSAGEBOX(M$)
!flagの値
LET MB_OK=00000000 ![OK]
LET MB_OKCANCEL=00000001 ![OK][キャンセル]
LET MB_ABORTRETRYIGNORE=00000002 ![中止][再試行][無視]
LET MB_YESNOCANCEL=00000003 ![はい][いいえ][キャンセル]
LET MB_YESNO=00000004 ![はい][いいえ]
LET MB_RETRYCANCEL=00000005 ![再試行][キャンセル]
!定数名 値 ボタンの種類
!IDOK= 1 !OK
!IDCANCEL= 2 !キャンセル
!IDABORT= 3 !中止
!IDRETRY= 4 !再試行
!IDIGNORE= 5 !無視
!IDYES= 6 !はい
!IDNO= 7 !いいえ
!定数名 値 アイコンの種類
LET MB_ICONSTOP=16 !0x00000010 停止のアイコン
LET MB_ICONQUESTION=32 !0x00000020 疑問符のアイコン
LET MB_ICONEXCLAMATION=48 !0x00000030 感嘆符のアイコン
LET MB_ICONINFORMATION=64 !0x00000040 吹き出しに「i」のアイコン
LET MESSAGEBOX=MESSBOX(0,M$,"BASIC",BITOR(MB_OKCANCEL,MB_ICONEXCLAMATION))
END FUNCTION
EXTERNAL FUNCTION MESSBOX(OWNER,TEXT$,CAPTION$,FLAG)
ASSIGN "user32.dll","MessageBoxA"
END FUNCTION
|
|
|
投稿者:しばっち
投稿日:2019年 9月12日(木)19時58分21秒
|
|
|
> No.4715[元記事へ]
SHIRAISHI Kazuoさんへのお返事です。
> 次のプログラムが,BASICAcc 1.2.0.2で動作します。
> 32ビット(Lazarus2.0.4 Win32版)
> 64ビット(Lazarus2.0.4 Win64版)
> どちらでも動作します。
> ANSI$関数は未公開かもしれませんが,suppliedsユニットで定義されています。
> (BASICAccは内部文字コードがUTF-8なので,日本語はANSI$を噛まさないと文字化けします。)
>
> FOR I=1 TO 3
> SELECT CASE MESSAGEBOX(ANSI$("よろしいですか ")&STR$(I))
> CASE 1
> PRINT "OK"
> CASE 2
> PRINT "CANCEL"
> END SELECT
> NEXT I
> END
こちらの環境で上記プログラムがBASICAcc 1.2.0.2で正常動作することを確認致しました。
Windows版BASIC 8.0.1.7についても、ダウンロードして正常動作を確認致しました。
但し、自作DLLでは動作しません。
原因は全く分かりません。コンパイルの仕方(オプション指定)なのでしょうか?
仕方ないのでWindows版 BASIC7854を使用します。
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月13日(金)06時10分11秒
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月13日(金)08時29分36秒
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月13日(金)14時07分30秒
|
|
|
> No.4719[元記事へ]
SHIRAISHI Kazuoさんへのお返事です。
BASICAcc自体は32ビットで動いているので,ASSIGN文を翻訳するときは32ビット版のDLLをテストしているの対し,実行時は64ビット版を要求するのが原因でした。
Windowsは,32ビットと64ビットで同名のDLLを持っているので動作していました。
> SHIRAISHI Kazuoさんへのお返事です。
>
> http://hp.vector.co.jp/authors/VA008683/MakeDLL_Laz.htm
> の例1を64ビットLazarusで試してみたら,
> BASICAccで
>
> [Warning]
> Syntax Error at line 3
> Sample.dll could not be loaded.
>
> となってしまいました。
> Lazarusで64ビットDLLを作るとWindows APIと仕様が異なるのかもしれません。
> でも,Lazarusで作ったDLLがLazarusのLoadLibraryで読み込めないのは不思議。
>
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月13日(金)15時38分11秒
|
|
|
> No.4720[元記事へ]
SHIRAISHI Kazuoさんへのお返事です。
> SHIRAISHI Kazuoさんへのお返事です。
> BASICAcc自体は32ビットで動いているので,ASSIGN文を翻訳するときは32ビット版のDLLをテストしているの対し,実行時は64ビット版を要求するのが原因でした。
> Windowsは,32ビットと64ビットで同名のDLLを持っているので動作していました。
Lazarus 64ビット版の「プロジェクトを開く」でsourceフォルダ内のBASIAccを指定し,
BASICAcc.dprの49行目
{$IFDEF Win32} ExtDll,{$ENDIF}
を
{$IFDEF Windows} ExtDll,{$ENDIF}
に書き換えてコンパイル。
すると,ExtDLL.pasの102行目
PUSH EAX
でエラーになるので,
Function RoundToLongint(x:extended):longint;assembler;
asm
PUSH EDX
PUSH EAX
FLD x
FISTP QWORD PTR [ESP]
WAIT
POP EAX
POP EDX
end;
をすべて削除して再度コンパイルしてください。
|
|
|
投稿者:しばっち
投稿日:2019年 9月13日(金)19時17分44秒
|
|
|
> No.4718[元記事へ]
SHIRAISHI Kazuoさんへのお返事です。
> 公開する関数にstdcall(C++では,__stdcall)を指定すること。
-------------------------------------------------------------------
airy_.cpp
#include <boost/math/special_functions/airy.hpp>
using namespace boost::math;
using namespace std;
extern "C" __declspec(dllexport) double airy_ai_(double *a)
{
try {
return airy_ai(*a);
} catch (...) {
return -99999999.0;
}
}
extern "C" __declspec(dllexport) double airy_bi_(double *a)
{
try {
return airy_bi(*a);
} catch (...) {
return -99999999.0;
}
}
EXTERNAL FUNCTION AIRY_AI(Z)
OPTION CHARACTER BYTE
LET X$=PACKDBL$(Z)
LET AIRY_AI=AIRY_AI_(X$)
FUNCTION AIRY_AI_(X$)
ASSIGN ".\DLL\airy_.dll","airy_ai_",FPU
END FUNCTION
END FUNCTION
EXTERNAL FUNCTION AIRY_BI(Z)
OPTION CHARACTER BYTE
LET X$=PACKDBL$(Z)
LET AIRY_BI=AIRY_BI_(X$)
FUNCTION AIRY_BI_(X$)
ASSIGN ".\DLL\airy_.dll","airy_bi_",FPU
END FUNCTION
END FUNCTION
__stdcallをつけずにコンパイルしたDLLは上記の定義でBASIC7854は動きます。(cdecl呼び出し規約)
__stdcallをつけてコンパイルしたDLLは下記のように訂正すればBASIC7854やBASIC 8017Jaでも動きました。(stdcall呼び出し規約)
C++では関数名が変わってしまうのようです。
EXTERNAL FUNCTION AIRY_AI(Z)
OPTION CHARACTER BYTE
LET X$=PACKDBL$(Z)
LET AIRY_AI=AIRY_AI_(X$)
FUNCTION AIRY_AI_(X$)
ASSIGN ".\DLL\airy_.dll","_airy_ai_@4",FPU
END FUNCTION
END FUNCTION
EXTERNAL FUNCTION AIRY_BI(Z)
OPTION CHARACTER BYTE
LET X$=PACKDBL$(Z)
LET AIRY_BI=AIRY_BI_(X$)
FUNCTION AIRY_BI_(X$)
ASSIGN ".\DLL\airy_.dll","_airy_bi_@4",FPU
END FUNCTION
END FUNCTION
いちいち関数名を調べるのは煩雑なので cdecl 呼び出し規約でBASIC7854のようにBASICAcc, BASIC8017Ja を動くようにできませんか?
http://home.a00.itscom.net/hatada/mcc/doc2012/functioncall.html
https://ja.wikipedia.org/wiki/呼出規約
また、作成したDLLファイルが別のDLL(ライブラリーでビルドしたdll等)を要求するような場合は、stdcallではコンパイルが通らないようです。(cdeclなら通る)
これは別のDLLが cdecl 呼び出し規約でビルドされているからなのかもしれません。
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年 9月15日(日)08時24分3秒
|
|
|
> No.4722[元記事へ]
Win64だとstdcallとcdeclが同じものになるので,64ビットであればcdeclで作成したものでも呼び出せるはずです。
Lazarus64ビット版でコンパイル
library Sample;
function add(a,b:Int64): Int64; cdecl;
begin
add:=a+b
end;
function sub(a,b:Int64): Int64; cdecl;
begin
sub:=a-b
end;
exports add, sub;
end.
BASICAccを64ビットでコンパイルしたものを使用
100 FUNCTION ADD(a,b)
110 ASSIGN "Sample.dll","add"
120 END FUNCTION
130
140 FUNCTION SUB(a,b)
150 ASSIGN "Sample.dll","sub"
160 END FUNCTION
170
180 PRINT ADD(5,-4),SUB(4,7)
190 END
DLLはBASICAccと同じディレクトリに置くか,フルパス名で指定してください。
実行結果
1 -3
|
|
|
投稿者:SHIRAISHI Kazuo
投稿日:2019年12月 9日(月)09時55分7秒
|
|
|
> No.4721[元記事へ]
SHIRAISHI Kazuoさんへのお返事です。
下記内容をBASICAcc1202_Win64.zipとして公開しました。
https://ja.osdn.net/projects/decimalbasic/releases/p9955
64ビットのDLLを使うプログラムをコンパイルすることができます。
> SHIRAISHI Kazuoさんへのお返事です。
>
> > SHIRAISHI Kazuoさんへのお返事です。
> > BASICAcc自体は32ビットで動いているので,ASSIGN文を翻訳するときは32ビット版のDLLをテストしているの対し,実行時は64ビット版を要求するのが原因でした。
> > Windowsは,32ビットと64ビットで同名のDLLを持っているので動作していました。
>
> Lazarus 64ビット版の「プロジェクトを開く」でsourceフォルダ内のBASIAccを指定し,
> BASICAcc.dprの49行目
> {$IFDEF Win32} ExtDll,{$ENDIF}
> を
> {$IFDEF Windows} ExtDll,{$ENDIF}
> に書き換えてコンパイル。
> すると,ExtDLL.pasの102行目
> PUSH EAX
> でエラーになるので,
>
> Function RoundToLongint(x:extended):longint;assembler;
> asm
> PUSH EDX
> PUSH EAX
> FLD x
> FISTP QWORD PTR [ESP]
> WAIT
> POP EAX
> POP EDX
> end;
>
> をすべて削除して再度コンパイルしてください。
>
|
|
|
戻る