2017-03-24 10 views
0

これは後でいくつかのクールなことをする前にテストするためにまとめた簡単なプロジェクトです。最終的な目標は、プログラムが素晴らしいdll kung fuを使用してモジュール性を処理できるようにすることです。AdaでカスタムDLLをリンクするにはどうすればよいですか?

しかし、赤ん坊のステップ。今はただのものにしたいだけです。

ここで私はAdder.adsを持っている:

package Adder is 

    function Add(A : Integer; B : Integer) return Integer; 

end Adder; 

とそれぞれAdder.adb:

package body Adder is 

    function Add(A : Integer; B : Integer) return Integer is 
    begin 
     return A + B; 
    end Add; 

end Adder; 

エキサイティングな、私は知っています。

私はこれを行う方法のいくつかの異なったチュートリアルを見てきたし、それらのどれもが同意していないが、this oneからヒントを取って、私はこれらのコマンドを思い付いた:

gnatmake -c Adder.adb 
gcc -shared -shared-libgcc -o Adder.dll Adder.o 

これは、少なくともAを生成し、 dll。私はそれが実際に動作するか、問題が主なexeである場合、それを生成するかどうか分からない。

私はgnatが.aliと.oファイルを不正行為して使用しようとしないように、メインのexeファイルをすべて別のディレクトリに保存しました。ビルドする前にdllをディレクトリにコピーします。私はさまざまな方法でこの微調整を試みましたが、いくつかの異なるエラーが出ましたが、今私が今持っているのはこれです。

Main.adb:これまで

with Adder_Spec; use Adder_Spec; 
with Ada.Text_IO; use Ada.Text_IO; 

procedure Main is 
begin 
    Put_Line(Integer'Image(Add(3,4))); 
end Main; 

イェーイほとんど役に立たないプログラム。今、私は、DLLのスペックを持つようになってる知って、私はaforewith'd Adder_Spec.adsを思い付いた:

package Adder_Spec is 

    function Add(A : Integer; B : Integer) return Integer; 

private 

    pragma Import(Ada, Add, "Add"); 

end Adder_Spec; 

を今、私はこの種類の方法の束試した言ったように、 3つ目のインポートパラメータを省略したり、インポートを省略したり、インポートを維持したり、プライベートな部分に分離したりしない場合もあります。私はまた、コンパイルコマンドで、いくつかの方法をプレイしようとしましたが、ここでは最新のものです:

gnatmake Main.adb -bargs -shared -largs -lAdder 

それは誤り「『追加』を未定義の参照」を出してくれる、この特定のコマンドで。 -vフラグを追加すると、それほど有用な情報は得られません。

gnatmake --helpをチェックすると、デフォルトモードがgnat 2012であることがわかります。おそらく、私は2005年と95年のフラグをコンパイルしようとしていたので、それはあまりないはずです。

だから誰にも分かりやすいですか?前もって感謝します。

+0

これはGNATの質問であり、Adaの質問ではありません(しかし、私は "ada"というタグをとっても合理的だと思います)。 –

+1

'gcc -shared -shared-libgcc -o Adder.dll -Adder.o'と言うと、あなたは単に' Adder.o'を意味すると思いますか? –

+0

@SimonWrightうん、良いキャッチ。 – Devsman

答えて

3

あなたは

package Adder_Spec is 
    function Add(A : Integer; B : Integer) return Integer; 
private 
    pragma Import(Ada, Add, "Add"); 
end Adder_Spec; 

を言いたい場合はDLLをインポートするとき、あなたはそれを構築するときに

package Adder is 
    function Add(A : Integer; B : Integer) return Integer; 
    pragma Export (Ada, Add, "Add"); 
end Adder; 

を言わなければなりません。

GNATのデフォルトのリンカ名は、Addの場合、adder__addとなります。 nm Adder.oを使って何が表示されているのかを確認できるはずです。

+0

AFAIKプラグマのエクスポートは、インポートされたコントラクト定義の直後に宣言する必要があります。そのスコープに関してあいまいさはありません。輸出が私的な部分で宣言され、公共の部分で契約されているとしたら、とにかく期待される行動は何でしょうか?なぜそのような構造が必要なのでしょうか? – LoneWanderer

+0

@LoneWanderer - [ARM05 B.1(51)](http://www.adaic.org/resources/add_content/standards/05rm/html/RM-B-1.html#p51)をチェックすると、私有部分で宣言された輸出。おそらく、関数呼び出しの結果に初期化された変数を宣言することによって、プラグマを見る前にサブプログラムを使用した場合、問題が生じる可能性があります。ここの例と上の例のアイデアは、本当に知る必要のない人の目から見えない詳細を隠すことでなければなりません。今日、もちろん、 'Convention'、' Export'と 'External_Name'の側面はあなたの顔にぴったりです! –

+0

あなたはダモン、サイモン。私はそのことを推測していたはずです。 – Devsman

0

AdaCoreの「Adaプラグインと共有ライブラリ」(part 1,part 2)の手順に従うことをお勧めします。

ここに記載されている手法を使用しましたが、それはかなりうまく機能しました。

+0

私はこれを間違いなく見ます。ありがとう! – Devsman

関連する問題