本帖最后由 850536360 于 2022-7-8 07:13 编辑
Go构建模式使用c-archive,生成C静态库,获得.a和.h文件。
例如:build.bat
set CGO_ENABLED=1
set GOOS=windows
set GOARCH=386
set ProjectName=sunny_mitm
set ProjectOutDir=%~dp0bin\windows\%ProjectName%\x86\
set ProjectOutPath_Lib=%ProjectOutDir%%ProjectName%.a
go build -buildmode=c-archive -ldflags "-s -w" -o "%ProjectOutPath_Lib%"
pause
.h为UTF-8编码,VC6使用需要转为ANSI编码。
编写对GO导出函数的调用 (考虑自动化处理。解析.h文件获取函数信息,以此生成代码)
例如:
//易库命令实现函数
extern "C" void lib_SetIeProxy(PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
SetIeProxy(pArgInf[0].m_bool);//调用GO导出的函数
}
易库编写详细说明见官方文档:易语言 目录\sdk\cpp\docs.txt
一些问题的临时解决方案
未支持MSVC
go/issues/20982
临时方案
使用MinGW构建
库的编译器不一致,编译缺少符号
go/issues/17014
临时方案
手动添加缺少的实现,比如:
#include <stdio.h>
//需要新建一个.c文件放实现
int __cdecl __mingw_vfprintf(
FILE *stream,
const char *format,
va_list argptr
)
{
return vfprintf(stream, format, argptr);
}
MSVC链接MinGW静态库,造成程序死锁
go/issues/30347
go/issues/42190
临时方案
手动调用 rt0_386_windows_lib 或 rt0_amd64_windows_lib。
或者在全局构造函数中实现自动调用。
#define GO_ARCHIVE
#ifdef GO_ARCHIVE
#ifndef _WIN64
extern "C" void rt0_386_windows_lib();
#else
extern "C" void rt0_amd64_windows_lib();
#endif
struct GlobalGoInit {
GlobalGoInit() {
#ifndef _WIN64
rt0_386_windows_lib();
#else
rt0_amd64_windows_lib();
#endif
}
} global_go_init;
不支持Freelibrary,导致易语言IDE打开支持库配置时程序崩溃
go/issues/11100
go/issues/32497
临时方案
双重引用计数,免疫FreeLibrary
int LockLibraryIntoProcessMem(HMODULE DllHandle, HMODULE *LocalDllHandle)
{
if(NULL == LocalDllHandle)
{
return ERROR_INVALID_PARAMETER;
}
*LocalDllHandle = NULL;
TCHAR moduleName[1024];
if(0 == GetModuleFileName(DllHandle, moduleName, sizeof(moduleName)/ sizeof(TCHAR)))
{
return GetLastError();
}
*LocalDllHandle = LoadLibrary(moduleName);
if(NULL == *LocalDllHandle){
return GetLastError();
}
return NO_ERROR;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
static HMODULE self = NULL;
LockLibraryIntoProcessMem(hModule, &self);
break;
}
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}