Preventing mangled names in Ada DLL

2019-07-05 06:46发布

问题:

Is there a simple way to prevent Ada names from getting mangled when creating an Ada DLL?

Here is my .adb code

with Ada.Text_IO;
package body testDLL is
   procedure Print_Call is
   begin
      Ada.Text_IO.Put_Line("Hello World");
   end Print_Call;

   function Add_Nums(A,B : in Integer) return Integer is
   begin
      return A + B;
   end Add_Nums;

end testDLL;

my .ads

package testDLL is
   procedure Print_Call;
   pragma export (dll, Print_Call, "Print_Call");

   function Add_Nums(A,B : in Integer) return Integer;
   pragma export (dll, Add_Nums, "Add_Nums");
end testDLL;

my python

import ctypes

TestDLL = ctypes.WinDLL ("libTestDLL.dll")
Print_Call = getattr(TestDLL, "Print_Call@0")
Print_Call()

you can see that I have to add '@0' to the end of my function name, but this seems to change when I move the same code to a different compiler. This is creating some problems for me. I need either a standard mangling format or a way to remove the mangling all together.

回答1:

You can control the object name via the Link_Name and External_Name parameters of the pragma, writing it like so:

pragma Export (C, Print_Call, "Print_Call", "Print_Call");

Alternatively, if you're using Ada2012 you can use aspects to specify these:

function Add_Nums(A,B : in Integer) return Integer
    with Export, Convention => Ada, Link_Name => "Add_Nums";

The following covers Ada's interfacing pragmas: http://www.ada-auth.org/standards/12rm/html/RM-J-15-5.html

This thread covers a little discussion revealing the differences of the two: https://groups.google.com/forum/?fromgroups=#!searchin/comp.lang.ada/opengl/comp.lang.ada/6IVlMbtvrrU/mv3UUiDg5RwJ



回答2:

Apparently (section 77) the convention DLL is a synonym for StdCall, which I understand to result in the sort of name mangling you report.

You may do better with convention C:

pragma Export (C, Print_Call, "Print_Call");

or even

pragma Export (C, Print_Call);

(but then the link name will be in lower case, so you'd need to change the Python getattr() call).

I'm assuming that there's no difference in the way the calling sequences handle the stack/parameters.