首頁 > 後端開發 > Golang > 使用 gcc (mingw32) 編譯帶有靜態函式庫的 DLL

使用 gcc (mingw32) 編譯帶有靜態函式庫的 DLL

PHPz
發布: 2024-02-09 10:00:11
轉載
1021 人瀏覽過

使用 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
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板