syscall.MustLoadDll.MustFindProc引发“找不到指定的过程”

时间:2018-12-11 09:37:16

标签: c++ go

我已经用c ++编写了一个动态链接库并正确导出了它,以便启用Go使用Win32 API来获取适配器信息。但是,当我在Go中调用其函数时,它将引发“找不到指定的过程”错误。 我对Go完全陌生,所以我不知道如何解决。有人可以帮我吗?

以下是有关我的环境的信息:

  

平台:Windows 10 x64

     

CXX编译器:Visual c ++ 15.3

     

运行版本:go1.11.2 Windows / amd64

这是我的代码:

#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;
}

这是我的golang代码:

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\n", str)
}

这是终端输出信息:

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

1 个答案:

答案 0 :(得分:0)

很有可能您遇到了C ++编译器在导出函数的名称上应用name mangling的效果,因此实际上并没有按照您期望的方式在库的导出表中命名。您可以使用objdump之类的工具或古老的depends.exe进行验证。最简单的方法是将导出的函数的声明包装到extern "C" { ... }中,请参阅this以获得复习。