🧼C, C++/라이브러리 강좌(옛날자료)

dll 만들기 - Python 에서 C언어 사용 - 2

Mawile 2020. 10. 5.
728x90

시작하기앞서서 사용한 운영체제는 Windows10이며,

IDE는 Devcpp,PythonIdle이고, 사용한 언어는 C++Python입니다.


dll만들기 - Python 에서 C언어 사용 - 1 (int형전달)

 

dll 만들기 - Python 에서 C언어 사용 - 1

안녕하세요! 오늘은 엄청 간단하고 쉽게 c언어의 함수를 python에서 실행할수있도록도와주는 동적연결라이브러리(다이내믹 라이브러리) 를 엄청 쉽게 만들건데요 IDE는 C언어의 Devcpp와 Python의 Pyth

mawile.tistory.com

위에올려논 글을 보신것처럼 기본셋팅을 맞춰주세요!!!

 

저번시간에는 int형전달에 대해 알아봤는데 이번시간에는 char형(문자열)전달에 대해 알아보겠습니다!!


먼저 DLL을 만들어주세요!

헤더파일과 cpp파일의 내용입니다!

 

그리고 cpp파일은 이렇게 바꿔줬습니다!

#include "dll.h"

extern "C"{
DLLS wchar_t* GetIntVar(const wchar_t *text){
	static wchar_t ret[10]={0};
    //wchar_t ret[10]또는 wchar_t *ret후 동적할당을 하지않는이유는
    //파이썬에서 DLL초기화에대한 내용을 불러오지못한 오류가 발생할수있습니다.
	wcscat(ret,text);
    //char형의 strcat을 wchar버전으로바꾼 함수
	wcscat(ret,L"hmm");
    //정해진내용은 옆에 'L'을 붙일것!
	return ret;
}
}

그리고 헤더파일의내용인데요

wchar헤더파일을 사용할겁니다

왜냐면

Python에서 그냥 char형을 하면 뒤에 bytes타입으로 형변환을 해줘야하는데

이때 옆에 'b'가 붙어서 안예쁩니다

밑에는 헤더파일의 내용입니다!

#define DLLS __declspec(dllexport)
#include <wchar.h> //wchar형 사용

이러면 저가 원하는값이면서 정상적으로나온다면 나올수있는값은 우선 text + "hmm" 이 되겠네요!!

 

파이썬예제코드도 보시겠습니다!

import ctypes

mydll = ctypes.WinDLL('C:\\(dll경로)\\blog-dll.dll')
GetIntVarP = mydll['GetIntVar'] #함수사용
GetIntVarP.argtypes = (ctypes.c_wchar_p,) #인자값 자료형설정
GetIntVarP.restype = ctypes.c_wchar_p #반환값 자료형설정

string = str(GetIntVarP("d"))
print(string)

한번 실행해보겠습니다!

잘 나오네요!

그러면 그냥 char형을 쓴다면 어떻게해야할까요??

일단 헤더파일을 추가해주시구요!

string.h

그런다음 함수를 추가해줍시다!

DLLS char* GetIntVars(const char *text){
	static char ret[10]={0};
	strcat(ret,text);
	strcat(ret,"char!");
	return ret;
}

파이썬코드는 어떻게바뀔까요??

import ctypes

mydll = ctypes.WinDLL('C:\\(dll경로)\\blog-dll.dll')
GetIntVarP = mydll['GetIntVar']
GetIntVarP.argtypes = (ctypes.c_wchar_p,)
GetIntVarP.restype = ctypes.c_wchar_p

GetIntVarPs = mydll['GetIntVars']
GetIntVarPs.argtypes = (ctypes.c_char_p,)
GetIntVarPs.restype = ctypes.c_char_p

#string = str(GetIntVarP("d"))
#print(string)

char = str(GetIntVarPs("d")) #오류발생코드

이러면 타입이 맞지않는다면서 에러가납니다! 그래서 bytes타입으로 형변환을 시켜줘야합니다!

import ctypes

mydll = ctypes.WinDLL('C:\\(dll경로)\\blog-dll.dll')
GetIntVarP = mydll['GetIntVar']
GetIntVarP.argtypes = (ctypes.c_wchar_p,)
GetIntVarP.restype = ctypes.c_wchar_p

GetIntVarPs = mydll['GetIntVars']
GetIntVarPs.argtypes = (ctypes.c_char_p,)
GetIntVarPs.restype = ctypes.c_char_p

#string = str(GetIntVarP("d"))
#print(string)

char = str(GetIntVarPs(b"python in ")) #'b <- bytes타입으로 캐스팅'
print(char)

이러면 정상작동합니다!

그러면 변수값을 전달하고싶으면 어떻게 형변환하면될까요?

[[   c코드수정   ]]

DLLS char* GetIntVars(char *text){ //const 제거
	static char ret[10]={0};
	strcat(ret,text);
	strcat(ret,"char!");
	return ret;
}

[[   파이썬코드수정   ]]

import ctypes

mydll = ctypes.WinDLL('C:\\(dll경로)\\blog-dll.dll')
GetIntVarP = mydll['GetIntVar']
GetIntVarP.argtypes = (ctypes.c_wchar_p,)
GetIntVarP.restype = ctypes.c_wchar_p

GetIntVarPs = mydll['GetIntVars']
GetIntVarPs.argtypes = (ctypes.c_char_p,)
GetIntVarPs.restype = ctypes.c_char_p

#string = str(GetIntVarP("d"))
#print(string)

byte = str(input()) #변수 'byte'안에 문자열값저장
char = GetIntVarPs(bytes(byte,encoding="utf-8"))
#변수 'char' 에다가 bytes타입으로 형변환을해준 변수 'byte' 대입
print(char)
#변수 'char' 출력

 

 

그러면~~~

오늘 DLL강좌는 이쯤하고 다음에는 더욱 다양한 자료형전달로 찾아뵙도록하겠습니다

DLL 기본강좌 다 끝내면은 DLL을 응용해서 C++과 python의 통합프로그램을 심화과정으로 알려드리겠습니다

긴글 봐주셔서 감삼니다!!

 

결과물 파일은 밑에 깃허브링크로 올려놨습니다!


다운로드

 

DRAGONPROCESS/DynamicLinkerLibrary-1

Contribute to DRAGONPROCESS/DynamicLinkerLibrary-1 development by creating an account on GitHub.

github.com

 

728x90

댓글