Как получить доступ к функции внутри файла DLL в Stack Overflow

В настоящее время я пытаюсь связаться с устройством с помощью CAN. Для этого я использую PCAN Basic с использованием C ++.

К сожалению, я ничего не знаю о доступе к функции внутри DLL-файла (что и предусмотрено). Я нашел эту ссылку:

Вызов функции dll из C ++

и я пытаюсь использовать LoadLibrary через код, который я нашел здесь:

http://www.goffconcepts.com/techarticles/development/cpp/calldll.html

Мой код:

// dll_get_func.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h> /* For sqrt() */
#include <windows.h>

#define DELCLDIR __declspec("Pcan_usb.dll")
#define PCAN_USBBUS1 0x51
#define CAN_BAUD_1M     0x0014  //   1 MBit/s
#define MSGTYPE_STANDARD 0x00

typedef struct {
DWORD ID;        // 11/29 bit identifier
BYTE  MSGTYPE;   // Bits from MSGTYPE_*
BYTE  LEN;       // Data Length Code of the Msg (0..8)
BYTE  DATA[8];   // Data 0 .. 7
} TPCANMsg;int hardCodeInit(void)
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary(_T("Pcan_usb.dll"));

/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"CAN_Init");

/*
Define the Function in the DLL for reuse. This is just prototyping the dll's function.
A mock of it. Use "stdcall" for maximum compatibility.
*/
typedef int (__stdcall * pICFUNC)(WORD wBTR0BTR1, int CANMsgType);

pICFUNC CAN_Init;
CAN_Init = pICFUNC(lpfnGetProcessID);
//DWORD __stdcall CAN_Init(WORD wBTR0BTR1, int CANMsgType);

/* The actual call to the function contained in the dll */
int intMyReturnVal = CAN_Init(PCAN_USBBUS1,CAN_BAUD_1M);

/* Release the Dll */
FreeLibrary(hGetProcIDDLL);

/* The return val from the dll */
return intMyReturnVal;
}
int hardCodeWrite(void)
{
HINSTANCE hGetProcIDDLL = LoadLibrary(_T("Pcan_usb.dll"));
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"CAN_Write");
typedef int (__stdcall * pICFUNC)(WORD wBTR0BTR1, TPCANMsg CANMsgType);
pICFUNC CAN_Write;
CAN_Write = pICFUNC(lpfnGetProcessID);

TPCANMsg msgOut;
msgOut.MSGTYPE = MSGTYPE_STANDARD;
msgOut.LEN = 1;
msgOut.DATA[0] = 0x03; // 0x03 = Get ID

int toReturn;
toReturn = CAN_Write(PCAN_USBBUS1,msgOut);
FreeLibrary(hGetProcIDDLL);
return toReturn;
}
int _tmain(int argc, _TCHAR* argv[])
{
int derp=hardCodeInit();
int herp=hardCodeWrite();
std::cout<<derp;
std::cout<<herp;
_getch();
return 0;
}

Тем не менее, Visual Studio говорит, что есть:

Unhandled exception at 0x10001D95 (Pcan_usb.dll) in dll_get_func.exe: 0xC0000005:
Access violation reading location 0x00000051.

У меня есть Pcan_usb.dll и Pcan_usb.lib в одной папке, и я использую Visual Studio 2012.

0

Решение

Здесь есть несколько моментов. Подпись LoadLibrary:

HMODULE WINAPI LoadLibrary(_In_  LPCTSTR lpFileName);

Удалить ненужные приведения. Это упростит чтение и понимание вашего кода.

FARPROC lpfnGetProcessID — имя переменной сбивает с толку. Это может быть источником путаницы или недопонимания.

Что касается AV — подпись функции CAN_Init, которую вы пытаетесь использовать, неверна. Из твоего поста сложно сказать наверняка, что должно быть. Изучите руководство (если возможно), заголовочный файл и т. Д.

Главное — не стоит выпускать библиотеку. Есть редкие случаи, когда это необходимо. Скорее всего, ваш случай не нуждается в этом. Очень трудно поверить, что вам нужно перезагрузить библиотеку (и это то, что происходит, когда вы вызываете FreeLibrary / LoadLibrary!) Между ее запуском и записью.

1

Другие решения

Access violation reading location 0x00000051.

Это говорит мне, что функция обрабатывает PCAN_USBBUS1 как указатель. Может быть:

#define PCAN_USBBUS1 0x51

следует изменить на

WORD pcan_usbbus1 = 0x51;

И призыв к CAN_Init следует изменить на:

int intMyReturnVal = CAN_Init(&pcan_usbbus1, CAN_BAUD_1M);

Сигнатура функции, вероятно, должна выглядеть примерно так:

typedef int (__stdcall * pICFUNC)(WORD* wBTR0BTR1, int CANMsgType);
^ pointer here

я представляю себе CAN_BAUD_1M может также потребоваться изменить таким же образом, но, возможно, нет.

1