php editor Baicao introduces you how to use gcc (mingw32) to compile a DLL with a static library. During the development process, it is often necessary to package static libraries into DLLs for easy calling in other projects. The method of using gcc (mingw32) to compile a DLL with a static library is relatively simple, just follow certain steps. First, make sure you have mingw32 and gcc compilers installed. Then, enter gcc -shared -o libname.dll libname.a on the command line to generate the DLL file. This way you can easily compile the static library into a DLL for use in other projects.
I have a static library generated by an external tool (i.e. cgo), let's call it libsecondary.a. I want to generate a dynamic library while including "libsecondary.a" as a dependency, I export a function called onprocessinit() in libsecondary.h and call it on the dll_process_attach event.
I tried generating the shared library but it doesn't seem to work x86_64-w64-mingw32-share-l. -lsecondary -static-libgcc -static-libstdc -static .\dllmain.c
The error output is dllmain.c:(.text 0x9b): Undefined reference to 'onprocessinit', what's going on?
This is the header file 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
This is dllmain.c
65be0f35ebbcbcThis is the exported golang function (the function I compiled using 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() {}
Wow, the answer is argument position,
x86_64-w64-mingw32 -shared -static-libgcc -static-libstdc -static .\dllmain.c .\libsecondary.a
If you type it backwards, it won't find the reference from libsecondary.a, OMG...
The above code will also get into a deadlock when loading, because syscall.NewLazyDLL calls LoadLibraryA, and it is locked in DLL_PROCESS_ATTACH, so the solution is to CreateThread and run the golang exported function inside the thread :)
The above is the detailed content of Compile DLL with static library using gcc (mingw32). For more information, please follow other related articles on the PHP Chinese website!