Home  >  Article  >  Backend Development  >  Compile DLL with static library using gcc (mingw32)

Compile DLL with static library using gcc (mingw32)

PHPz
PHPzforward
2024-02-09 10:00:11971browse

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

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.

Question content

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

65be0f35ebbcbc

This 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() {}

Solution

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete