C / C ++로 DLL을 컴파일 한 다음 다른 프로그램에서 호출
하나 또는 두 개의 함수를 내보내는 단순하고 간단한 DLL을 만든 다음 다른 프로그램에서 호출하려고합니다. 지금까지 살펴본 모든 곳은 복잡한 문제, 서로 다른 연결 방법, 이상한 문제에 대한 것입니다. 나는 아직 존재한다는 것을 깨닫기 시작 하지도 않았다 ... 나는 단지 다음과 같은 일을함으로써 시작하고 싶다.
다음과 같은 일부 기능을 내보내는 DLL을 만듭니다.
int add2(int num){
return num + 2;
}
int mult(int num1, int num2){
int product;
product = num1 * num2;
return product;
}
나는 MinGW로 컴파일하고 있는데, C로 이것을하고 싶지만, C ++로하는 실제적인 차이점이 있다면 이것도 알고 싶습니다. 해당 DLL을 다른 C (및 C ++) 프로그램에로드 한 다음 해당 함수를 호출하는 방법을 알고 싶습니다. 여기서 내 목표는 DLL을 잠시 사용해 본 후 DLL을 Visual Basic으로로드하여 C (++) 코드 용 VB 프런트 엔드를 만드는 것입니다 (Visual Studio 6이 있고 몇 가지 양식을 만들고 싶습니다. DLL을 호출하는 해당 양식의 개체에 대한 이벤트).
DLL을 생성하기 위해 gcc (/ g ++)를 호출하는 방법과 내보내기 파일을 작성 (/ 생성)하는 방법을 알아야합니다. 그리고 DLL에서 할 수있는 / 할 수없는 작업 (예 : VB 프런트 엔드에서 포인터 / 참조에 의한 인수? DLL이 프런트 엔드에서 이론적 함수를 호출 할 수 있습니까? 또는 함수가 VB에서 "함수 포인터"(가능한지 모르겠습니다)를 가져와 호출 그것은?) 나는 DLL에 변종을 전달할 수 없다고 확신한다. 그러나 그것이 내가 정말로 아는 전부이다.
다시 업데이트
좋아, 내가 실행 한 dll을 만들기 위해 gcc로 컴파일하는 방법을 알아 냈다.
gcc -c -DBUILD_DLL dll.c
gcc -shared -o mydll.dll dll.o -Wl,--out-implib,libmessage.a
그런 다음 다른 프로그램에서로드하고 기능을 테스트했습니다. 정말 잘 작동했습니다. 조언에 감사드립니다.하지만 다음과 같이 VB6으로로드 해 보았습니다.
Public Declare Function add2 Lib "C:\c\dll\mydll.dll" (num As Integer) As Integer
그런 다음 양식에서 add2 (text1.text)를 호출했지만 런타임 오류가 발생했습니다.
"C : \ c \ dll \ mydll.dll에서 DLL 진입 점 add2를 찾을 수 없습니다."
이것은 DLL 용으로 컴파일 한 코드입니다.
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
EXPORT int __stdcall add2(int num){
return num + 2;
}
EXPORT int __stdcall mul(int num1, int num2){
return num1 * num2;
}
그래도 다음과 같이 C 프로그램에서 호출하면 효과가 있습니다.
#include<stdio.h>
#include<windows.h>
int main(){
HANDLE ldll;
int (*add2)(int);
int (*mul)(int,int);
ldll = LoadLibrary("mydll.dll");
if(ldll>(void*)HINSTANCE_ERROR){
add2 = GetProcAddress(ldll, "add2");
mul = GetProcAddress(ldll, "mul");
printf("add2(3): %d\nmul(4,5): %d", add2(3), mul(4,5));
} else {
printf("ERROR.");
}
}
어떤 아이디어?
그것을 해결했다
이전 문제를 해결하기 위해 다음과 같이 컴파일해야했습니다.
gcc -c -DBUILD_DLL dll.c
gcc -shared -o mydll.dll dll.o -Wl,--add-stdcall-alias
VB6에서이 API 호출을 사용합니다.
Public Declare Function add2 Lib "C:\c\dll\mydll" _
(ByVal num As Integer) As Integer
ByVal 또는 ByRef를 명시 적으로 지정하는 것을 잊지 않는 법을 배웠습니다. 전달한 인수의 주소를 돌려 받았습니다. -3048처럼 보입니다.
MinGW를 사용하여 DLL을 빌드하는 것과 관련하여 다음은 매우 간단한 지침입니다.
먼저 함수를 내보낼 수 있도록 표시해야 DLL 호출자가 사용할 수 있습니다. 이렇게하려면 다음과 같이 수정하십시오 (예 :
__declspec( dllexport ) int add2(int num){
return num + 2;
}
그런 다음 함수가 funcs.c라는 파일에 있다고 가정하면 컴파일 할 수 있습니다.
gcc -shared -o mylib.dll funcs.c
-shared 플래그는 gcc에게 DLL을 생성하도록 지시합니다.
DLL이 실제로 함수를 내보냈는지 확인하려면 무료 Dependency Walker 도구를 가져 와서 DLL을 검사하십시오.
DLL을 빌드하는 데 필요한 모든 플래그 등을 자동화하는 무료 IDE의 경우 MinGW와 매우 잘 작동 하는 우수한 Code :: Blocks를 살펴보십시오 .
편집 : 이 주제에 대한 자세한 내용 은 MinGW Wiki의 Visual Basic 에서 사용할 MinGW DLL 만들기 문서를 참조하십시오 .
방법은 다음과 같습니다.
.h에서
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
extern "C" // Only if you are using C++ rather than C
{
EXPORT int __stdcall add2(int num);
EXPORT int __stdcall mult(int num1, int num2);
}
.cpp에서
extern "C" // Only if you are using C++ rather than C
{
EXPORT int __stdcall add2(int num)
{
return num + 2;
}
EXPORT int __stdcall mult(int num1, int num2)
{
int product;
product = num1 * num2;
return product;
}
}
The macro tells your module (i.e your .cpp files) that they are providing the dll stuff to the outside world. People who incude your .h file want to import the same functions, so they sell EXPORT as telling the linker to import. You need to add BUILD_DLL to the project compile options, and you might want to rename it to something obviously specific to your project (in case a dll uses your dll).
You might also need to create a .def file to rename the functions and de-obfuscate the names (C/C++ mangles those names). This blog entry might be an interesting launching off point about that.
Loading your own custom dlls is just like loading system dlls. Just ensure that the DLL is on your system path. C:\windows\ or the working dir of your application are an easy place to put your dll.
There is but one difference. You have to take care or name mangling win C++. But on windows you have to take care about 1) decrating the functions to be exported from the DLL 2) write a so called .def file which lists all the exported symbols.
In Windows while compiling a DLL have have to use
__declspec(dllexport)
but while using it you have to write __declspec(dllimport)
So the usual way of doing that is something like
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
The naming is a bit confusing, because it is often named EXPORT.. But that's what you'll find in most of the headers somwhere. So in your case you'd write (with the above #define)
int DLL_EXPORT add.... int DLL_EXPORT mult...
Remember that you have to add the Preprocessor directive BUILD_DLL during building the shared library.
Regards Friedrich
The thing to watch out for when writing C++ dlls is name mangling. If you want interoperability between C and C++, you'd be better off by exporting non-mangled C-style functions from within the dll.
You have two options to use a dll
- Either use a lib file to link the symbols -- compile time dynamic linking
- Use
LoadLibrary()
or some suitable function to load the library, retrieve a function pointer (GetProcAddress
) and call it -- runtime dynamic linking
Exporting classes will not work if you follow the second method though.
For VB6:
You need to declare your C functions as __stdcall, otherwise you get "invalid calling convention" type errors. About other your questions:
can I take arguments by pointer/reference from the VB front-end?
Yes, use ByRef/ByVal modifiers.
Can the DLL call a theoretical function in the front-end?
Yes, use AddressOf statement. You need to pass function pointer to dll before.
Or have a function take a "function pointer" (I don't even know if that's possible) from VB and call it?)
Yes, use AddressOf statement.
update (more questions appeared :)):
to load it into VB, do I just do the usual method (what I would do to load winsock.ocx or some other runtime, but find my DLL instead) or do I put an API call into a module?
You need to decaler API function in VB6 code, like next:
Private Declare Function SHGetSpecialFolderLocation Lib "shell32" _
(ByVal hwndOwner As Long, _
ByVal nFolder As Long, _
ByRef pidl As Long) As Long
ReferenceURL : https://stackoverflow.com/questions/847396/compile-a-dll-in-c-c-then-call-it-from-another-program
'Program Tip' 카테고리의 다른 글
“brew link”는 무엇을합니까? (0) | 2020.12.27 |
---|---|
가상 상속 (0) | 2020.12.27 |
Android NDK 및 STLport에서 boost 라이브러리 (shared_ptr 포함)를 사용하는 방법 (0) | 2020.12.27 |
요청 받기가 액세스 제어 검사를 통과하지 못함 : 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. (0) | 2020.12.27 |
데이터베이스에 디렉토리 / 계층 구조 / 트리 구조를 저장하는 방법은 무엇입니까? (0) | 2020.12.27 |