syscall.MustLoadDll.MustFindProc выдает «Указанная процедура не найдена» - PullRequest
0 голосов
/ 11 декабря 2018

Я написал библиотеку динамических ссылок на c ++ и правильно ее экспортировал, чтобы позволить Go получать информацию об адаптере с помощью Win32 API.Но когда я вызываю его функцию в Go, он выдает ошибку «Указанная процедура не найдена».Я полностью новичок в Go, поэтому понятия не имею, как это решить.Кто-нибудь может мне помочь?

Вот некоторая информация о моей среде:

платформа: windows 10 x64

CXX компилятор: визуальный c ++ 15,3

версия go: 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 голосов
/ 11 декабря 2018

Скорее всего, вы столкнулись с тем, что ваш компилятор C ++ применил искажение имени к имени экспортируемой функции, поэтому оно действительно не названо так, как вы ожидаете в таблице экспорта библиотеки.Вы можете проверить это с помощью таких инструментов, как objdump или, скажем, почтенный depends.exe.Самый простой подход - заключить объявление вашей экспортируемой функции в extern "C" { ... } - см. this для обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...