이곳저곳에서 본 내용을 짜집기 해서 만든 내용입니다.
밑에 참고했던 내용들을 달아놨으니, 혹시 필요하시면 찾아가 보시기 바랍니다.
1. C++로 코드 작성하기
1) 코드 바로 작성하기 예제
#include <stdio.h> extern "C" // 여기에 내용내용내용 |
2) 선언과 정의를 따로 분리하실경우, 선언은 다음과 같이
extern "C" __declspec(dllimport) void Start_DebugView(); |
2. C++ 프로젝트 Property Setting
먼저 , C++로 만든 프로젝트에서 다음과 같이 설정을 해 줍니다. (꼭)
다음과 같이 설정해주시지 않으면, C#에서 DLL을 Import하여도 실제로 Lo
ad가 되지 않습니다...(그러면 삽질을 하게되요... ... 누구처럼??)
3. C#에서 사용하기
C++로 만든 dll은 기존의 C#의 dll을 사용하던 것 처럼 reference에 추가해서 사용하실 수 없습니다.
그래서 코드에 직접 , 사용한다고 선언해주고 사용하여야 합니다.
먼저, C++을 이용해서 만든 dll을 필요한 위치에 위치 시킵니다. 저같은 경우 실행파일과 같은 위치에 위치하였습니다. (*)
그런 뒤 ,
1 ) using System.Runtime.InteropServices; NameSpace를 추가한 후
2 ) [DllImport("TestLib.dll")] 를 이용하여 사용할 Dll을 명시한 후 사용할 함수를 선언합니다.
(* 실행파일과 같은 위치에 있으면 dll의 이름만 쓰시면 됩니다. 아닌경우 주소까지 같이 명시)
3) 그리고 그냥 함수처럼 사용하시면 됩니다.
using System; class HelloWorld static void Main () |
* 줏은 Tip
이래저래 귀찮다.. 하시면
엔진은 CLR을 사용하지 않고 Native Code로 컴파일하고 엔진을 Wrapping 하는 CLR C++ 프로젝트를 하나 더 만들고,
그 프로젝트를 참조하여 C#에서 사용하는 방법이 있습니다.
주의 ) 어쩌면 더 귀찮아 지실수도... 있습니다.
* 하지만 약간의 디버깅이 가능하고, 밑의 파라미터 관련하여 포팅도 가능합니다!!!
* 한 가지 추가
C++에서 사용하는 클래스와, C#에서 사용하는 클래스가 다르기 때문에, 파라미터 사용에 대해서 약간의 포팅이 필요합니다.
예를들면 다음과 같습니다.
1) C++ 선언
HWND FindWindow(LPCSTR swClassName, LPCSTR swTitle); |
2) C# 선언
[DllImport(“user32.dll”)] public static extern int FindWindow(string a, string b); |
설명 )
HWND는 윈도우 핸들을 표현하는 32비트 정수 이므로, int형으로 치환되고 LPCSTR 형은 NULL로 끝나는 문자열을 표현합니다.
이때 PInvoke는 string을 자동으로 LPCSTR로 치환해 주는 역할을 하게 됩니다.
WIN32 데이터형의 치환
Win32 API에서 일반적으로 사용하고 있는 데이터형은 모두 C#의 데이터 형으로 치환될 수 있습니다.
Win32 API TYPE |
C# |
BOOL, BOOLEAN |
bool |
BYTE |
byte |
CALLBACK |
delegate |
COLORREF |
int |
DWORD |
int |
DWORD_PTR |
long |
DWORD32 |
uint |
DWORD64 |
ulong |
FLOAT |
float |
HACCEL |
int |
HANDLE |
int |
HBITMAP |
int |
HBRUSH |
int |
HCONV |
int |
(모든 HANDLE 타입) Hxxxx |
int |
LPARAM |
long |
LPCSTR |
[in] string [out] StringBuilder |
LPBOOL |
ref bool |
이외 LP* 형 |
ref 형식 |
UINT |
uint |
Uxxxx |
unsigned 타입들.. |
WORD |
Short |
WPARAM |
Uint |
C++의 경우 char가 1byte, C#의 경우 char가 2byte이기 때문에 ,,,,
위에서 LPCSTR 가 [in] string [out] StringBuilder와 바로 호환이 된다고해서 좋다고 사용하였다가, 인코딩이 다 깨져서 낭패를 봤습니다..... ㅠ_ㅠ (거짓말쟁이)
이 경우는 다음과 같이 해결하였습니다.
1) C++ 선언
extern "C" __declspec(dllexport) void Save_DebugView_Path(char* Save_Path); |
2) C# 선언
[DllImport("OutputDebugString_HookingDll.dll")] public static extern void Save_DebugView_Path([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string pFileName); |
다음과 같이 사용하면,
(한글을 사용하지 않는 이상) 글자가 깨지지 않고 잘 전달되는 모습을 확인하실 수 있습니다..
Attribute에서 명시적으로 String에 대해 LPWStr로 변환해서 넘겨주도록 지정하고 있기 때문이에요.
아래와 같은 과정이 자동으로 수행된다 생각하셔도 되겠습니다.
string Path = @"c:\test.txt"; IntPtr PathPtr = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(Path); // ~~~~~~~~~~~~~~~~~~~~ //Char *PathPointer = (Char*)PathPtr.ToPointer(); // ~~~~~~~~~~~~~~~~~~~~ System.Runtime.InteropServices.Marshal.FreeHGlobal(PathPtr); |
... 네 그렇습니다..
그 외의 특별한 경우는 밑에 참고를 잘 뒤져보시면 몇몇개 나옵니다.. 될지안될지는 못믿겠습니다...ㅠㅠ(위에서 한개 안되니까 ... 장담하긴어렵네요..)
이상으로 마칩니다. 감사합니다.
참고)
http://www.codeproject.com/KB/cs/usecdlllibincs.aspx
http://www.mdfo.kr/tag/UnmanagedType
http://sonic.tistory.com/entry/CC%EB%A1%9C-%EB%A7%8C%EB%93%A0-DLL-Library%EB%A5%BC-C%EC%97%90%EC%84%9C-%EC%93%B0%EA%B8%B0
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=17&MAEULNO=8&no=113249&ref=113249&page=31
http://hoons.kr/Board.aspx?Name=QACSHAP&Mode=2&BoardIdx=24982&Key=&Value=
http://www.hoons.kr/Board.aspx?Name=cshaptip&Mode=2&BoardIdx=21751&Key=&Value=
http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040102&docId=67700148&qb=U3RydWN0TGF5b3V0
감사합니다...참고할께요.
출처: http://perfectcrimelab.com/136?srchid=BR1http%3A%2F%2Fperfectcrimelab.com%2F136
'IT-개발,DB' 카테고리의 다른 글
[VC++] 문자열변환 CString LPSTR WCHAR* LPCWSTR (0) | 2010.09.10 |
---|---|
c# delay 함수 / C# Delay function (0) | 2010.09.10 |
[Win32] ActiveX 컨트롤 등록 (0) | 2010.09.08 |
[VC++] DLL이나 OCX를 레지스트리에 등록하거나 제거..(regsvr32) (0) | 2010.09.07 |
[MFC/Win] ActiveX killbit, 사용안함 처리 (0) | 2010.09.07 |
댓글