Test fine, maybe you called Microsoft-Windows-Only api. Try to change MessageBox() (it using win32 user32.dll) to Sum() to test c-dll which called go-dll.
Here is go file to gen go-dll
// gosum.go
package main
/*
#include <stdlib.h>
*/
import "C"
//export Sum
func Sum(a int32, b int32) int32 {
return a + b
}
func main() {
}
Go build c-shared Windows dll:
go build -ldflags "-s -w" -buildmode=c-shared -o gosum.dll
you can write test file in c/cpp:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "gosum.h"
int main() {
printf("Sum(1,2)=%d\n", Sum(1,2));
return 1;
}
Compiled it in MinGW-w64
g++ -c test_gosum.cpp -o test_gosum.o -g -std=c++11
g++ test_gosum.o gosum.dll -o test_gosum.exe -g -std=c++11
.\test_gosum.exe

Then to build loader.dll in Visual Studio which called gosum.dll
// copy go-dll CGO gen gosum.h file to project, may be you need remove some error code
// gosum.h file:
/* Code generated by cmd/cgo; DO NOT EDIT. */
/* package gosum */
#line 1 "cgo-builtin-export-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#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. */
#line 3 "gosum.go"
#include <stdlib.h>
#line 1 "cgo-generated-wrapper"
/* 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 float GoFloat32;
typedef double GoFloat64;
/*
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 GoInt32 Sum(GoInt32 a, GoInt32 b);
#ifdef __cplusplus
}
#endif
// pch.h file(gen by vs, need add something):
#define PCH_H
#include "framework.h"
#endif
// ----- added
#ifdef IMPORT_DLL
#else
#define IMPORT_DLL extern "C" _declspec(dllimport)
#endif
IMPORT_DLL int get_sum_by_another_dll(int a, int b);
// ----- added
// dllmain.cpp file(gen by vs):
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// loader.cpp file:
#include "pch.h"
#include <stdlib.h>
#include <windows.h>
#include "gosum.h" // also need add `gosum.dll` to VS project file
using namespace std;
typedef int (CALLBACK* GOSUMFUNC)(GoInt32 a, GoInt32 b);
int __stdcall get_sum_by_another_dll(int a, int b)
{
HMODULE h = LoadLibrary(TEXT("gosum.dll"));
if (NULL == h || INVALID_HANDLE_VALUE == h) {
return 0;
}
GOSUMFUNC go_dll_sum = (GOSUMFUNC)GetProcAddress(h, "Sum");
if (go_dll_sum) {
return go_dll_sum(a, b);
}
return 1;
}
then compiled them in VS, you will get loader.dll.
there gosum.dll is go-dll, loader.dll is c-dll compiled by VisualStudio which called gosum.dll.

you can try call them in golang or clang.
// demo.go test loader.dll and gosum.dll with golang, also need to copy gosum.dll and loader.dll in same dir.
package main
import (
"fmt"
"log"
"syscall"
)
func main() {
h, e := syscall.LoadLibrary("loader.dll") //Make sure this DLL follows Golang machine bit architecture (64-bit in my case)
if e != nil {
log.Fatal(e)
}
defer syscall.FreeLibrary(h)
proc, e := syscall.GetProcAddress(h, "get_sum_by_another_dll") //One of the functions in the DLL
if e != nil {
log.Fatal(e)
}
var a int32 = 2
var b int32 = 5
ret, _, err := syscall.Syscall(proc, 2, uintptr(a), uintptr(b), 0) //Pay attention to the positioning of the parameter
fmt.Println(ret)
fmt.Println(err)
}
go run it you will get result: get_sum_by_another_dll(2,5) = 7

// callloader.cpp test loader.dll and gosum.dll with c/cpp, also need to copy gosum.dll and loader.dll in same dir.
#include <iostream>
#include <Windows.h>
int main()
{
HINSTANCE hDllInst;
hDllInst = LoadLibrary(L"loader.dll");
typedef int(*SUMFUNC)(int a, int b);
SUMFUNC dll_sum_fun = (SUMFUNC)GetProcAddress(hDllInst, "get_sum_by_another_dll");
std::cout << dll_sum_fun(1, 2);
}
then compiled it in VS, run ./callloader.exe, you will get result: get_sum_by_another_dll(1,2) = 3
