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

7eumitmz  于 2023-02-06  发布在  Go
关注(0)|答案(1)|浏览(397)

我有一个静态库,让我们称之为libsecondary. a,它由外部工具(即CGO)生成。我想生成一个动态库,同时将“libsecondary. a”作为依赖项,我在libsecondary. h中导出一个名为OnProcessInit()的函数,并在DLL_PROCESS_ATTACH事件中调用它。
我尝试使用x86_64-w 64-mingw 32-shared -L. -lsecondary -static-libgcc -static-libstdc++ -static.\dllmain. c生成共享库,但似乎失败了
错误输出为dllmain.c:(.text+0x 9 b):未定义对“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

#include <windows.h>
#include <stdio.h>
#include "libsecondary.h"

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        printf("It works i guess");
        OnProcessInit();
        break;

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        break;
    }

    return TRUE;
}

这是导出的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() {}
hof1towb

hof1towb1#

答案是论点的立场
x86_64-w 64-mingw 32-共享-静态-libgcc-静态-libstdc ++ -静态。\dll主文件夹. c.\辅助文件夹. a
如果你把它倒着打,它就找不到libsecondary.a的引用了,天啊...
另外,上面的代码在加载时会陷入死锁,因为syscall.NewLazyDLL调用LoadLibraryA,并且它在DLL_PROCESS_ATTACH内部被锁定,所以要做的是创建线程并在线程内部运行golang导出函数:)

相关问题