登录
首页 >  Golang >  Go问答

如何使用 gcc (mingw32) 编译包含静态库的动态链接库

来源:stackoverflow

时间:2024-02-29 08:18:24 469浏览 收藏

本篇文章向大家介绍《如何使用 gcc (mingw32) 编译包含静态库的动态链接库》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。

问题内容

我有一个由外部工具(即 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 

#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 
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) 编译包含静态库的动态链接库》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>