win64版十進BASICのリリースを

 投稿者:しばっち  投稿日:2019年 9月 8日(日)19時10分42秒
  十進BASIC上から64ビットDLL(x64)を呼び出したいので、Windows版十進BASIC(win64版)を
(テスト版、ベータ版でも)出して欲しいのですが、無理でしょうか?
 

Re: win64版十進BASICのリリースを

 投稿者: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

 

Re: win64版十進BASICのリリースを

 投稿者:しばっち  投稿日: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ではこれらは問題なく動きます。

 

Re: win64版十進BASICのリリースを

 投稿者: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/

 

Re: win64版十進BASICのリリースを

 投稿者: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
 

Re: win64版十進BASICのリリースを

 投稿者:しばっち  投稿日: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を使用します。
 

Re: win64版十進BASICのリリースを

 投稿者:SHIRAISHI Kazuo  投稿日:2019年 9月13日(金)06時10分11秒
  > No.4717[元記事へ]

自作DLLは,普通に作ると動作しないと思います。
ただし,64ビットは普通に作っても同じかもしれません。

公開する関数にstdcall(C++では,__stdcall)を指定すること。
http://hp.vector.co.jp/authors/VA008683/MakeDLL_Laz.htm

http://hp.vector.co.jp/authors/VA008683/

 

Re: win64版十進BASICのリリースを

 投稿者:SHIRAISHI Kazuo  投稿日:2019年 9月13日(金)08時29分36秒
  > No.4718[元記事へ]

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で読み込めないのは不思議。

http://hp.vector.co.jp/authors/VA008683/

 

Re: win64版十進BASICのリリースを

 投稿者: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で読み込めないのは不思議。
>
 

Re: win64版十進BASICのリリースを

 投稿者: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;

をすべて削除して再度コンパイルしてください。
 

Re: win64版十進BASICのリリースを

 投稿者:しばっち  投稿日: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 呼び出し規約でビルドされているからなのかもしれません。
 

Re: win64版十進BASICのリリースを

 投稿者: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
 

Re: win64版十進BASICのリリースを

 投稿者: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;
>
> をすべて削除して再度コンパイルしてください。
>
 

戻る