Как мне написать тело функции в dll, но иметь прототип в моей основной программе - PullRequest
0 голосов
/ 30 мая 2020

Извините, если вопрос элементарный, я новичок в .dll-s. В основном я хочу, чтобы моя функция имела доступ к тем же глобальным переменным, что и в основной программе, в которой она изначально определена, в то время как на самом деле она написана в примере .dll

: у меня есть объект ListView, в котором я нахожусь печать сообщений из функции

void example(){
//Display is my listview
Display->Items->Add("Hello world");
}

в этом примере Display - это объект TListView, который инициализируется в моем main. cpp, из которого я определяю поведение моей формы приложения VCL. Этот объект Display является глобальной переменной в основном cpp, и из-за этого, когда я вырезаю example () и вставляю его в свою новую dll, он ломается, потому что в пределах диапазона dll Display не существует.

Моя идея - объявить прототип функции void example (); в main.h и НЕКОТОРЫЕ напишите тело в мою dll, но когда я включаю <"something"> в dll, компилятор кричит, что idk, что я пытаюсь сделать ...

Какие у меня options?

Я использую построитель c ++, но предполагаю, что тот же логический вопрос применим к любой IDE

1 Ответ

0 голосов
/ 30 мая 2020

Вы все делаете неправильно. DLL не может получить доступ к переменным, которые находятся вне ее, как в основном EXE, если внешний код не дает указатели / ссылки DLL на них. Что в любом случае вам не поможет в приведенном вами примере.

Лучше всего вообще не разрешать DLL напрямую обращаться к переменным. В вашем примере вы должны заставить EXE передать указатель на функцию обратного вызова в DLL, которую DLL может затем вызвать при необходимости. Внутренне эта функция может использовать переменные EXE по мере необходимости.

Например:

MyDLL.h

#ifndef MyDLL_H
#define MyDLL_H

#ifdef BUILDING_DLL
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif

typedef void (__stdcall *myTextCallback)(const char *text, void *userData);

MY_API void __stdcall dll_setTextCallback(myTextCallback userCallback, void *userData);

#endif

MyDll. cpp

#define BUILDING_DLL
#include "MyDll.h"

myTextCallback textCallback = NULL;
void *textCallbackData = NULL;

void __stdcall dll_setTextCallback(myTextCallback userCallback, void *userData)
{
    textCallback = userCallback;
    textCallbackData = userData;
}

void doSomething()
{
    ...
    if (textCallback)
        textCallback("Hello World", textCallbackData);
    ...
}

EXE

#include "MyDll.h"

void __stdcall displayText(const char *text, void *userData)
{
    TListItem *Item = static_cast<TMainForm*>(userData)->Display->Items->Add();
    Item->Caption = text;
}

__fastcall TMainForm::TMainForm(TComponent *Owner)
    : TForm(Owner)
{
    dll_setTextCallback(&displayText, this);
}

__fastcall TMainForm::~TMainForm()
{
    dll_setTextCallback(NULL, NULL);
}

Таким образом, DLL не должна знать или заботиться о том, что EXE хочет делать с данными DLL.

...