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中文網其他相關文章!