DllMain/DllMainCRTStartup不在DLL中执行

DllMain/DllMainCRTStartup不在DLL中执行,dll,ada,gnat,Dll,Ada,Gnat,导入时,带有gnat的DLL生成中的初始化代码不会自动运行。我做了一个MCVE,包括: 部门广告 with System; with Interfaces.C; package Division is --Neither of these work procedure DllMainCRTStartup ; pragma Export (StdCall, DllMainCRTStartup , "DllMainCRTStartup"); --Edited as noticed

导入时,带有gnat的DLL生成中的初始化代码不会自动运行。我做了一个MCVE,包括:

部门广告

with System;
with Interfaces.C;

package Division is
   --Neither of these work
   procedure DllMainCRTStartup ;
   pragma Export (StdCall, DllMainCRTStartup , "DllMainCRTStartup"); --Edited as noticed by Brian
   -- procedure DllMain
   -- pragma Export (StdCall, DllMain , "DllMain ");

   function Div (A : in INTEGER; B : in INTEGER) return INTEGER;
   pragma Export (C, Div, "MyDivision");

   -- --If I put this, it does not compile... maybe a wrong linkage option set?
   -- procedure AdaInit; 
   -- pragma Import (C, AdaInit, "adainit");
end Division;
亚洲开发银行分部

with text_io;

package body Division is
   procedure DllMainCRTStartup  is begin --DllMain or DllMainCRTStartup
      text_io.put("INIT CODE YEAH!!!*************!"); --This does not execute :(
      --AdaInit;
   end DllMainCRTStartup ;

   function Div(A : in INTEGER; B : in INTEGER) return INTEGER is
      X : INTEGER := A/B;
   begin
      return X;
   end Div;
end Division;
和gpr:

library project Proj_Name is
  for Library_Name use "math";
  for Object_Dir use "obj";
  for Source_Dirs use ("src");
  for Library_Dir use "lib";
  for Library_Interface use ("Division");
  for Library_Kind use "dynamic";
  for Library_Options use ("-LC:\GNAT\2015\lib\gcc\i686-pc-mingw32\4.9.3\adalib",
                           "-LC:\GNAT\2015\lib\gcc\i686-pc-mingw32\4.9.3\adalib\libgnat");
end Proj_Name;
我正在用ctypes测试python中的dll。我使用ctypes.CDLL导入它,并且可以使用MyDivision。但是,导入dll时不会运行init代码,因为不会执行文本io

另一方面,如果我将AdaInit过程添加到代码中,则在编译时会得到如下结果:

undefined reference to `adainit'

多谢各位

我不确定您如何知道初始化代码没有运行

我在macOS上运行,但是Ada方面应该是类似的。我编写了这个软件包规范/正文,作为您的更简单版本:

包划分为
函数Div(A:整数;B:整数)返回整数;
布拉格出口(C,部门,“MyDivision”);
端部划分;
使用Ada.Text_IO;
包体分部是
函数Div(A:整数;B:整数)返回整数为
X:整数:=A/B;
开始
返回X;
结束Div;
详细说明的程序测试是
开始
Ada.Text_IO.Put_Line(“你好,世界!”);
结束测试_进行_细化;
开始
测试_进行_细化;
端部划分;
用这个更简单的探地雷达

库项目名称为
对于库名称,使用“数学”;
对于Object_Dir,使用“obj”;
供来源地使用(“src”);
对于库目录,使用“lib”;
用于图书馆与U接口使用(“部门”);
对于图书馆类,使用“动态”;
结束项目名称;
并使用此C代码进行了测试:

#include <stdio.h>

extern int MyDivision(int, int);

int main()
{
  printf("42 / 2 => %d\n", MyDivision(42, 2));
  return 0;
}

很明显,对我来说,图书馆精化是不需要我做任何事情的

原因是您在项目文件中指定了
Library\u接口
,这意味着您正在构建一个

是一个包含必要代码的库,用于详细说明库中包含的Ada单元。独立库是一种方便的方法,可以将Ada子系统添加到一个更全局的系统中,该系统的主要部分不在Ada中,因为它使Ada部分的细化变得更加透明

您可以使用指定一个不会自动初始化的独立动态库

for Library_Auto_Init use "false";
在这种情况下,您需要自己调用库的初始化过程;它被称为
{library name}init
(在您的例子中是
mathinit
)。但是你需要从你的主程序调用它;它需要用C语言声明

extern void mathinit();

“adainit”不是你写的或提供的东西。在任何Ada代码之前,框架通常会运行它来初始化Ada RTS,比如在c程序中调用main()之前运行“crt0.c”(通常是不可见的)。但是,这并不能解释为什么没有调用DLL启动。一个奇怪的现象:为什么导出的名称中有空格?Ups。。。打字错误但是,我更改了它,但它不起作用:(啊,你得到了解决方案!谢谢!我认为在导入名为DllMain的函数时,导出要运行的函数就足够了。似乎这不是解决方法,因为在你的解决方案中,你使用begin Test_进行细化;end Division;D'oh!我应该注意到没有包初始化代码。。。
extern void mathinit();