2017-03-24 70 views
0

因此,這是一個簡單的項目,我之前將它們放在一起進行測試,然後再做一些很酷的事情。最終的目標是讓程序能夠通過真棒dll功夫來處理模塊化。如何鏈接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 

這至少產生 dll。我不知道它是否會生成一個實際上可以工作的問題,或者如果問題出在主要的exe文件上。

現在主要的exe文件,我把所有東西放在一個單獨的目錄下,所以gnat不會試圖欺騙和使用.ali和.o文件。然後,在嘗試構建之前將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; 

現在,就像我說我已經試過這一堆不同的方式,有時省略第三個導入參數,其他時間完全省略導入,有時保留導入但不將其分隔到私有部分,您可以將其命名。我也試着用編譯命令打幾個方面,但這裏是最近的一個:

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