使用 gnat 对“do_varargs"的未定义引用 [英] undefined reference to 'do_varargs' with gnat

查看:31
本文介绍了使用 gnat 对“do_varargs"的未定义引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编译后,当我尝试使用 win32ada 2017 和 GNAT 2017 构建我的 DLL 时,它发出错误:

After the compilation, when I try to build my DLL with win32ada 2017 and GNAT 2017, it issues an error :

gnatlink <ali\file> -o <jnk\file> -mdll -Wl,base-file,<base\file>  
win32-winuser.o:win32-winuser.adb:(.text+0xa62): undefined reference to 'do_varargs'  
win32-winuser.o:win32-winuser.adb:(.text+0x15be): undefined reference to 'do_varargs'  
collect2.exe: error: ld returned 1 exit status  
gnatlink: error when calling C:\GNAT\2017\bin\gcc.exe

你知道为什么 gnatlink 会出现这个错误吗?

Do you know why gnatlink issues this error ?

fichier pour la compiler situé dans un dossier :

fichier pour la compilation situé dans un dossier :

@echo on

set GNAT_PATH=C:\GNAT\2017
set gnatbin=%GNAT_PATH%\bin
set winada=%GNAT_PATH%\lib\win32ada

set path=%gnatbin%;%path%;

set INTERFACE_DLL=..

set obj=%INTERFACE_DLL%\obj

set GCCARGS=-c -g -O3 -mfentry -fomit-frame-pointer -gnatf 
set GNATMAKEARGS=-gnatwu -v -gnato -I%winada% 

cd %INTERFACE_DLL%\%obj%
%gnatbin%\gnatmake %GNATMAKEARGS% ..\hello_dll.adb  -cargs %GCARGS%

Le fichier pour la création de la DLL:

Le fichier pour la création de la DLL :

gnatdll -k -d hello_dll.dll obj\hello_dll.ali

Je ne peux pas afficher ici mon fichier pour lequel j'ai produit l'erreur mais j'ai reproduit sur des fichiers plus simples ci-dessous :le fichier adb

Je ne peux pas afficher ici mon fichier pour lequel j'ai produit l'erreur mais j'ai reproduit sur des fichiers plus simples ci-dessous : le fichier adb

with System;
use System;

with Win32;
with Win32.Windef;
with Interfaces.C.Strings;
with Win32.Winuser;
package body HELLO_DLL is
    procedure Report is 
          Result     : Win32.Int         := 0;
          H_Wnd      : Win32.Windef.Hwnd := Null_Address;  
          Lp_Text    : Win32.Lpcstr      := Win32.To_Pcstr (Interfaces.C.Strings.New_String ("Hello World"));  
          Lp_Caption : Win32.Lpcstr      := Win32.To_Pcstr (Interfaces.C.Strings.New_String ("Hello World 2"));  
          U_Type     : Win32.Uint        := 0;  

   begin
      Result := Win32.Winuser.Messagebox (H_Wnd, Lp_Text, Lp_Caption, U_Type);
    end Report;
end HELLO_DLL;

更高级的广告

   with Interfaces.C;
    package HELLO_DLL is

    procedure Report;             
   end HELLO_DLL;

推荐答案

Bonjour :-) 您的 gnatdll 似乎缺少对 win32ada 库的引用> 论据.你可能想试试这个(注意最后三个附加参数):

Bonjour :-) It seems that you're missing a reference to the win32ada library in your gnatdll arguments. You might want to try this (note the last three additional arguments):

gnatdll -k -d hello_dll.dll obj\hello_dll.ali -I"C:\GNAT\2017\lib\win32ada.relocatable" -largs -lwin32ada

然而,话虽如此,我实际上认为使用 GNAT 项目文件创建 DLL 比使用 gnatdll 更容易.根据您的示例(我对其进行了一些修改),我一次性从下面的文件和命令行创建了一个 DLL.如果构建成功,lib 目录将包含一个 DLL:

However, that being said, I actually think it's easier to create a DLL using a GNAT project file instead of using gnatdll. Based on your example (which I modified a little bit), I created a DLL from the files below and from the command-line in one go. The lib directory will contain a DLL if the build succeeds:

> gprbuild -p -XWIN32ADA_BUILD=relocatable -P .\hello.gpr
Setup
   [mkdir]        object directory for project Hello
   [mkdir]        library directory for project Hello
Compile
   [Ada]          hello.adb
Build Libraries
   [gprlib]       hello.lexch
   [bind SAL]     hello
   [Ada]          b__hello.adb
   [link library] libhello.dll

src/hello.ads

package Hello is

   procedure Initialize
     with Export, Convention => C;

   procedure Finalize
     with Export, Convention => C;

   procedure Say_Hello
     with Export, Convention => C;

end Hello;

src/hello.adb

with System; use System;
with Interfaces.C.Strings;

with Win32;
with Win32.Windef;
with Win32.Winuser;

package body Hello is

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
      procedure helloinit with Import;       --  Generated by binder.
   begin
      helloinit;
   end Initialize;

   --------------
   -- Finalize --
   --------------

   procedure Finalize is
      procedure hellofinal with Import;      --  Generated by binder.
   begin
      hellofinal;
   end Finalize;

   ---------------
   -- Say_Hello --
   ---------------

   procedure Say_Hello is

      package C_Str renames Interfaces.C.Strings;

      C_Text    : C_Str.chars_ptr := C_Str.New_String ("Hello World!");
      C_Caption : C_Str.chars_ptr := C_Str.New_String ("A Hello World Dialog.");

      Result : Win32.Int := 0;

   begin      
      Result := Win32.Winuser.Messagebox 
        (hWnd      => Null_Address,
         lpText    => Win32.To_Pcstr (C_Text),
         lpCaption => Win32.To_Pcstr (C_Caption),
         uType     => 0);

      --  Don't forget to free the allocated strings.
      C_Str.Free (C_Text);
      C_Str.Free (C_Caption);      

   end Say_Hello;

end Hello;

hello.gpr

with "win32ada";

library project Hello is

   for Library_Kind use "dynamic";   
   for Library_Name use "hello";
   for Library_Interface use ("hello");

   --  The "Library_Auto_Init" option is set to False. This will make the binder
   --  generate initialization and finalization functions (in this case
   --  "helloinit" and "hellofinal"). It's a good habit to wrap these
   --  and call these wrappers from the client application.   

   for Library_Auto_Init use "False";

   for Library_Dir use "lib";
   for Object_Dir use "obj";
   for Source_Dirs use ("src");

end Hello;

lib/libhello.def(导出的符号,区分大小写,这里必须小写)

lib/libhello.def (exported symbols, case-sensitive, must be lower case here)

LIBRARY   LIBHELLO
EXPORTS
    initialize
    finalize
    say_hello

<小时>

额外:使用 Visual Studio 2019 测试 DLL

为了测试 DLL,我决定使用 Visual Studio CE 2019 创建一个小型应用程序.我首先使用库管理器(lib 工具)创建了一个导入库.从我调用的x64 Native Tools Command Prompt for VS 2019"中:

To test the DLL, I decided to create a small application using Visual Studio CE 2019. I first created an import library using the Library Manager (lib tool). From the "x64 Native Tools Command Prompt for VS 2019" I invoked:

> lib /machine:X64 /def:./lib/libhello.def /out:./lib/libhello.lib
Microsoft (R) Library Manager Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.

   Creating library libhello.lib and object libhello.exp

然后我创建了一个新文件夹,并用下面的源文件和之前创建的文件 libhello.dlllibhello.alibhello 填充它.经验.我终于使用

I then the created a new folder and populated it with the source files below and the previously created files libhello.dll, libhello.a and libhello.exp. I finally complied it (again, from the "x64 Native Tools Command Prompt for VS 2019") using

cl HelloApp.cpp libhello.lib
Microsoft (R) C/C++ Optimizing Compiler Version 19.26.28806 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

HelloApp.cpp
Microsoft (R) Incremental Linker Version 14.26.28806.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:HelloApp.exe
HelloApp.obj
libhello.lib

这个新的 HelloApp.exe 显示(如预期)一个对话框.请注意,libhello.dll 依赖于 GNAT 运行时库(检查 dependency walker),因此请确保(在您的情况下)C:\GNAT\2017\bin 在运行应用程序时位于搜索路径上(或将所需的 DLL 复制到与 HelloApp 相同的文件夹中).exe).

This new HelloApp.exe shows (as expected) a dialog box. Note that the libhello.dll depends on the GNAT runtime library (check with the dependency walker), so make sure that (in your case) C:\GNAT\2017\bin is on the search path when running the application (or copy the required DLLs to the same folder as HelloApp.exe).

hello.h

#pragma once

extern "C"
{
    extern void  say_hello();
    extern void  initialize();
    extern void  finalize();
}

HelloApp.cpp

#include <windows.h>
#include "hello.h"

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    UNREFERENCED_PARAMETER(hInstance);
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(pCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    initialize();
    say_hello();
    finalize();

    return 0;
}

这篇关于使用 gnat 对“do_varargs"的未定义引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆