Niewidoczna funkcja w DLL

0

dll_test.dll :

extern "C" __declspec(dllexport)void MultiplyBy(int,int);

int MulitplyBy(int value,int multiplier)
{

	return value*multiplier;
}

program testujący:

#include <iostream>
#include <Windows.h>



using namespace std;




int main()
{
	HMODULE hModule = LoadLibrary("C:\\dll_test.dll"); 	
	
	

	if (hModule == NULL) 
	MessageBoxW(0,L"Error with getting handle to module",L"Error!",0);

	int hMultiplyBy = (int)GetProcAddress (hModule, "MultiplyBy");

	if (hMultiplyBy == NULL) 
	MessageBoxW(0,L"Error with getting handle to the function",L"Error!",0);

	//cout<<MultiplyBy(5,5);

	FreeLibrary (hModule);

	cout<<endl;
	system("PAUSE");
	return 0;
}

Nie rozumiem dlaczego program nie może uchwycić funkcji MultiplyBy...

0

Znalazłem błąd w dll'ce , typ funkcji z deklaracji nie zgadzał się z typem w definicji .

Poprawiłem...

extern "C" __declspec(dllexport)int MultiplyBy(int,int);
 
int MulitplyBy(int value,int multiplier)
{
 
        return value*multiplier;
}

... ale funkcja jakimś cudem dalej jest niewykrywalna.

0

spróbuj nazwę z podkreślnikiem na początku jak używasz funkcji GetProcAddress ("_funkcja" zamist "funkcja")

0

Bez zmian.

0

Na moje oko jest to problem z dekorowaniem, które dzieje się gdy eksportujesz funkcję c++. Każdy kompilator dokleja do nazwy inne znaki, w celu odróżnienia kilku przeładowanych wersji. Pozostaje Ci albo wrzucić definicję funkcji do extern "C", albo podejżeć jakimś programem typu DEPENDS jakie nazwy zostały im przypisane, i podpinać się do udekorowanej wersji.

0

Nie dekorowanie jest problemem, bo to załatwia extern "C".

Ale mieszasz ładowanie statyczne DLL z ładowaniem dynamicznym.

W programie testującym:

int hMultiplyBy = (int)GetProcAddress (hModule, "MultiplyBy");
cout<<MultiplyBy(5,5);

Skąd kompilator ma w drugiej linijce wiedzieć, co to jest MultiplyBy? Najbliższe nazwą jest hMultiplyBy, ale przecież to tylko int.

Po pierwsze, DLL-ka powinna mieć osobny plik .h z eksportowanymi funkcjami. Ponieważ raz potrzeba dllexport, a raz nie, to można zrobić przez odpowiednie #define:


dll_test.h ```cpp #pragma once

#ifdef DLL_TEST_EXPORT

define DLL_TEST_API extern "C" __declspec(dllexport)

#else

ifdef __cplusplus

define DLL_TEST_API extern "C"

else

define DLL_TEST_API

endif

#endif

DLL_TEST_API int MultiplyBy(int value, int multiplier);

<hr>

Teraz DLL-ka:
<hr><b>dll_test.c</b> lub <b>dll_test.cpp</b>
```cpp
// kompilacja: cl dll_test.cpp /LD
#define DLL_TEST_EXPORT
#include "dll_test.h"

DLL_TEST_API int MulitplyBy(int value,int multiplier)
{
 
        return value*multiplier;
}

Po kompilacji powstanie nam `dll_test.dll`, biblioteka importowa `dll_test.lib`, i niepotrzebny nam na razie plik `dll_test.exp`.

Teraz linkowanie statyczne - prostsze:


program_stat.cpp ```cpp // kompilacja: cl program_stat.cpp dll_test.lib /EHsc #include <iostream>

#include "dll_test.h"

using namespace std;

int main()
{
cout<<MultiplyBy(5,5) << endl;
}

</hr>

<i>(linkowanie dynamiczne dopiszę później)</i>

1 użytkowników online, w tym zalogowanych: 0, gości: 1