首页  >  文章  >  后端开发  >  使用 gcc (mingw32) 编译带有静态库的 DLL

使用 gcc (mingw32) 编译带有静态库的 DLL

PHPz
PHPz转载
2024-02-09 10:00:11970浏览

使用 gcc (mingw32) 编译带有静态库的 DLL

php小编百草为你介绍如何使用gcc (mingw32)编译带有静态库的DLL。在开发过程中,经常需要将静态库打包成DLL以便于在其他项目中调用。使用gcc (mingw32)编译带有静态库的DLL的方法相对简单,只需按照一定的步骤操作即可。首先,确保已安装mingw32和gcc编译器。然后,在命令行中输入gcc -shared -o libname.dll libname.a即可生成DLL文件。通过这种方式,你可以轻松地将静态库编译为DLL,以便在其他项目中使用。

问题内容

我有一个由外部工具(即 cgo)生成的静态库,我们将其称为 libsecondary.a。我想生成一个动态库,同时包含“libsecondary.a”作为依赖项,我在 libsecondary.h 中导出一个名为 onprocessinit() 的函数,并在 dll_process_attach 事件上调用它。

我尝试生成共享库,但似乎无法使用 x86_64-w64-mingw32-共享-l。 -lsecondary -static-libgcc -static-libstdc++ -static .dllmain.c

错误输出是 dllmain.c:(.text+0x9b): 未定义对“onprocessinit”的引用,这是怎么回事?

这是头文件libsecondary.h

/* code generated by cmd/cgo; do not edit. */

/* package command-line-arguments */


#line 1 "cgo-builtin-export-prolog"

#include <stddef.h>

#ifndef go_cgo_export_prologue_h
#define go_cgo_export_prologue_h

#ifndef go_cgo_gostring_typedef
typedef struct { const char *p; ptrdiff_t n; } _gostring_;
#endif

#endif

/* start of preamble from import "c" comments.  */




/* end of preamble from import "c" comments.  */


/* start of boilerplate cgo prologue.  */
#line 1 "cgo-gcc-export-header-prolog"

#ifndef go_cgo_prologue_h
#define go_cgo_prologue_h

typedef signed char goint8;
typedef unsigned char gouint8;
typedef short goint16;
typedef unsigned short gouint16;
typedef int goint32;
typedef unsigned int gouint32;
typedef long long goint64;
typedef unsigned long long gouint64;
typedef goint64 goint;
typedef gouint64 gouint;
typedef size_t gouintptr;
typedef float gofloat32;
typedef double gofloat64;
#ifdef _msc_ver
#include <complex.h>
typedef _fcomplex gocomplex64;
typedef _dcomplex gocomplex128;
#else
typedef float _complex gocomplex64;
typedef double _complex gocomplex128;
#endif

/*
  static assertion to make sure the file is being used on architecture
  at least with matching size of goint.
*/
typedef char _check_for_64_bit_pointer_matching_goint[sizeof(void*)==64/8 ? 1:-1];

#ifndef go_cgo_gostring_typedef
typedef _gostring_ gostring;
#endif
typedef void *gomap;
typedef void *gochan;
typedef struct { void *t; void *v; } gointerface;
typedef struct { void *data; goint len; goint cap; } goslice;

#endif

/* end of boilerplate cgo prologue.  */

#ifdef __cplusplus
extern "c" {
#endif

extern __declspec(dllexport) void onprocessinit();

#ifdef __cplusplus
}
#endif

这是 dllmain.c

65be0f35ebbcbc

这是导出的 golang 函数(我使用 go build -buildmode=c-archive 编译的函数)

package main
import "C"
import (
    "unsafe"
    "syscall"
)

//export OnProcessInit
func OnProcessInit() {
    const (
        NULL  = 0
        MB_OK = 0
    )
    caption := "Hola"
    title := "desdegoo"
    ret, _, _ := syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW").Call(
        uintptr(NULL),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
        uintptr(MB_OK))

    if ret != 1 {
        return
    }
    return 
}

func main() {}

解决方法

哇,答案是论证位置,

x86_64-w64-mingw32 -shared -static-libgcc -static-libstdc++ -static .dllmain.c .libsecondary.a

如果你向后输入它,它将找不到来自 libsecondary.a 的引用,天哪......

上面的代码在加载时也会陷入死锁,因为 syscall.NewLazyDLL 调用 LoadLibraryA,并且它被锁定在 DLL_PROCESS_ATTACH 中,所以解决方法是 CreateThread 并在线程内运行 golang 导出函数:)

以上是使用 gcc (mingw32) 编译带有静态库的 DLL的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除