I have written a dynamic link library in c++ and export it correctly, in order to enable Go to fetch adapter infomation using Win32 API. But when I call its function in Go, it throws "The specified procedure could not be found" error. I'm totally new with Go, so I have no idea how to solve it. Could anybody help me?
Here's some infomation about my environment:
platform: windows 10 x64
CXX compiler: visual c++ 15.3
go version: go1.11.2 windows/amd64
Here is my code:
#include "stdafx.h"
#include <WinSock2.h>
#include <iphlpapi.h>
#include <iostream>
#include <vector>
using namespace std;
__declspec(dllexport) const char *get_default_gateway();
vector <string> default_gateway;
const char *get_default_gateway()
{
PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
PIP_ADAPTER_INFO info_p;
unsigned long stSize = sizeof(IP_ADAPTER_INFO);
int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
info_p = pIpAdapterInfo;
if (ERROR_BUFFER_OVERFLOW == nRel)
{
delete pIpAdapterInfo;
pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
info_p = pIpAdapterInfo;
}
if (ERROR_SUCCESS == nRel)
{
while (info_p)
{
IP_ADDR_STRING *pIpAddrString = &(info_p->IpAddressList);
do
{
string gateway_tmp = info_p->GatewayList.IpAddress.String;
if (gateway_tmp != "0.0.0.0") {
default_gateway.push_back(info_p->GatewayList.IpAddress.String);
}
pIpAddrString = pIpAddrString->Next;
} while (pIpAddrString);
info_p = info_p->Next;
}
}
if (pIpAdapterInfo)
{
delete []pIpAdapterInfo;
}
const char *gateway = default_gateway.at(0).c_str();
return gateway;
}
Here is my golang code:
package main
import (
"fmt"
"syscall"
"unsafe"
)
func main() {
dll := syscall.MustLoadDLL("getAdapterInfo.dll")
getDefaultGateWay := dll.MustFindProc("get_default_gateway")
r, _, _ := getDefaultGateWay.Call()
p := (*byte)(unsafe.Pointer(r))
data := make([]byte, 0)
for *p != 0 {
data = append(data, *p)
r += unsafe.Sizeof(byte(0))
p = (*byte)(unsafe.Pointer(r))
}
str := string(data)
fmt.Printf("%s
", str)
}
Here is the terminal output info:
panic: Failed to find get_default_gateway procedure in getAdapterInfo.dll:
The specified procedure could not be found.
goroutine 1 [running]:
syscall.(*DLL).MustFindProc(0xc000056400, 0x4c4934, 0x13, 0xc000081f48)
E:/Go/src/syscall/dll_windows.go:109 +0x80
main.main()
E:/GOPATH/src/github.com/Arktische/test/main.go:11 +0x67
Chances are high you've hit the effect of your C++ compiler applying name mangling to the name of your exported function, so it really is not named the way you expect in the library's export table. You can verify that with tools like objdump or, say, the venerable depends.exe
. The simplest approach is to wrap the declaration of your exported function into extern "C" { ... }
—see this for a refresher.