반응형
이전 글에서 DLL 만드는 방법에 대한 소개가 있음.
이번 글에선 DLL 로드해서 함수 사용해볼거임.
개발 환경: C++ builder 11.3
컴포넌트 추가 어떻게 하는지는 생략하겠음.
버튼하나 만들어 줘야겠져?
코드 구현
Unit2.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
Row=SGTitle->RowCount;
Col=SGTitle->ColCount;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormShow(TObject *Sender)
{
SGTitle->Cells[0][0]="title";
for(int row = 0; row<Row; row++)
{
for(int col = 0; col<Col; col++)
{
SGTitle->Cells[col][row]=col+row*Row;
}
}
LoadDLL();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
UnloadDLL();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::BtnCalculateClick(TObject *Sender)
{
String A = EditA->Text;
String B = EditB->Text;
int a = A.ToInt();
int b = B.ToInt();
//여기까지가 UI 상입력한 숫자값 받아오는 부분이고
//아래에 입력받은 숫자값을 DLL에 추가해주면 되겠죠?
if (MyFunction && Add)
{
MyFunction(); // DLL의 함수 호출
int result = Add(a, b); // Add 함수 호출
EditC->Text =IntToStr(result);
STDllStatus->Caption = "DLL 로드 성공 및 계산 완료";
}
else
{
STDllStatus->Caption = "DLL을 로드하지 못했습니다.";
}
}
//---------------------------------------------------------------------------
// DLL을 로드하는 함수
void TForm2::LoadDLL() {
//HINSTANCE hInstance = LoadLibrary(L"C:\\Users\\wooch\\OneDrive\\문서\\Embarcadero\\Studio\\Projects\\MyDLibrary.dll");
HINSTANCE hInstance = LoadLibrary(L"MyDLibrary.dll");
if (!hInstance) {
DWORD error = GetLastError();
STDllStatus->Caption = error ;
return;
}
// 함수 포인터에 DLL의 함수 주소를 할당
MyFunction = (VoidFunction)GetProcAddress(hInstance, "MyFunction");
Add = (AddFunction)GetProcAddress(hInstance, "Add");
if (!MyFunction || !Add) {
std::cerr << "함수를 찾을 수 없습니다." << std::endl;
FreeLibrary(hInstance);
hInstance = nullptr;
}
}
//---------------------------------------------------------------------------
// DLL을 해제하는 함수
void TForm2::UnloadDLL() {
if (hInstance) {
FreeLibrary(hInstance);
hInstance = nullptr;
}
}
//---------------------------------------------------------------------------
Unit2.h
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.Grids.hpp>
#include <Data.DB.hpp>
#include <Data.Win.ADODB.hpp>
//---------------------------------------------------------------------------
#include <windows.h> // LoadLibrary와 GetProcAddress 사용을 위해 필요
//---------------------------------------------------------------------------
// DLL에서 가져올 함수 포인터 선언
typedef void (*VoidFunction)();
typedef int (*AddFunction)(int, int);
class TForm2 : public TForm
{
__published: // IDE-managed Components
TStringGrid *SGTitle;
TADOConnection *ADOConnection1;
TEdit *EditA;
TEdit *EditB;
TStaticText *StaticText1;
TStaticText *StaticText2;
TButton *BtnCalculate;
TStaticText *STDllStatus;
TEdit *EditC;
void __fastcall FormShow(TObject *Sender);
void __fastcall BtnCalculateClick(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
VoidFunction MyFunction; // 함수 포인터 변수
AddFunction Add; // 함수 포인터 변수
HINSTANCE hInstance; // DLL 핸들
public: // User declarations
int Row,Col;
__fastcall TForm2(TComponent* Owner);
void LoadDLL(); // DLL을 로드하는 함수 선언
void UnloadDLL(); // DLL을 해제하는 함수 선언
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif
unit2.dfm
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 441
ClientWidth = 624
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
OnClose = FormClose
OnShow = FormShow
TextHeight = 15
object SGTitle: TStringGrid
Left = 472
Top = 352
Width = 612
Height = 401
TabOrder = 0
Visible = False
RowHeights = (
24
24
24
24
24)
end
object EditA: TEdit
Left = 56
Top = 80
Width = 121
Height = 23
TabOrder = 1
end
object EditB: TEdit
Left = 208
Top = 80
Width = 121
Height = 23
TabOrder = 2
end
object StaticText1: TStaticText
Left = 190
Top = 84
Width = 12
Height = 19
Caption = '+'
TabOrder = 3
end
object StaticText2: TStaticText
Left = 335
Top = 84
Width = 12
Height = 19
Caption = '='
TabOrder = 4
end
object BtnCalculate: TButton
Left = 488
Top = 79
Width = 75
Height = 25
Caption = 'Calculate'
TabOrder = 5
OnClick = BtnCalculateClick
end
object STDllStatus: TStaticText
Left = 80
Top = 44
Width = 4
Height = 4
TabOrder = 6
end
object EditC: TEdit
Left = 353
Top = 80
Width = 121
Height = 23
TabOrder = 7
end
object ADOConnection1: TADOConnection
Left = 544
Top = 392
end
end
문제가 많음.
1번 문제는 builder는 32bit 까지만 지원해서 64bit dll이 로드가 안됨.
visual studio로 돌아가서 프로젝트 설정 변경해서 로드함.
2번 문제는 DLL 로드가 안되던 문제.
오류코드 216은 dll로드가 안된 경우 발생함. 이게 발생하면 dll 경로 먼저 체크해주면 됨.
프로젝트 경로랑 동일한 경로에 dll을 위치시켰으나, 로드가 안됨. 이유를 모르겠음.
절대경로로 그냥 지정해버리는 걸로 해결함.
해보다가 안 사실인데 프로젝트 위치가 cpp 파일 있는 곳이 아니라 컴파일 된 exe 파일이 있는 위치였음.
반응형
'C++ Programming' 카테고리의 다른 글
[C++] DLL 만들기(Visual Studio) (0) | 2024.10.23 |
---|---|
[C++] Map 공부 (0) | 2024.07.06 |
[C++ Programming] 문자열 변환 c_str() 함수 (0) | 2024.07.06 |
[C++] Vector 공부 (0) | 2024.07.06 |
[C++ Programming] Template을 사용한 Doubly Linked List 구현 (1) | 2024.03.17 |