首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DllMain/DllMain启动在DLL中不执行

DllMain/DllMain启动在DLL中不执行
EN

Stack Overflow用户
提问于 2016-11-23 12:52:33
回答 1查看 328关注 0票数 1

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

division.ads

代码语言:javascript
复制
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;

division.adb

代码语言:javascript
复制
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;

与探地雷达:

代码语言:javascript
复制
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;

我正在用ctype测试python中的dll。我用ctypes.CDLL导入它,并且我能够使用MyDivision。但是,由于未执行text_io,所以导入dll时不运行init代码。

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

代码语言:javascript
复制
undefined reference to `adainit'

非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-23 20:00:58

我不知道你怎么知道初始化代码没有运行?

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

代码语言:javascript
复制
package Division is

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

end Division;

with Ada.Text_IO;
package body Division is

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

   procedure Test_For_Elaboration is
   begin
      Ada.Text_IO.Put_Line ("hello world!");
   end Test_For_Elaboration;

begin
   Test_For_Elaboration;
end Division;

用这个更简单的探地雷达

代码语言:javascript
复制
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";
end Proj_Name;

并使用此C代码进行了测试:

代码语言:javascript
复制
#include <stdio.h>

extern int MyDivision(int, int);

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

结果是

代码语言:javascript
复制
$ ./caller 
hello world!
42 / 2 => 21

因此,很明显,对我来说,图书馆的精益求精并不需要我做任何事情。

原因是您在项目文件中指定了Library_Interface,这意味着您正在构建一个独立图书馆,其中

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

您可以指定独立的动态库,该库不会自动初始化。

代码语言:javascript
复制
for Library_Auto_Init use "false";

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

代码语言:javascript
复制
extern void mathinit();
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40765088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档