dongzhou4727 2018-12-11 09:37
浏览 330
已采纳

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

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
  • 写回答

1条回答 默认 最新

  • dp19001 2018-12-11 11:46
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?