4. BigInteger 코딩 - DLL호출 메서드
BigInteger의 메서드들을 순수한 C#으로 코딩할 수도 있으나, 여기서는 앞 장에서 C로 작성한 큰 수를 처리하는 함수들을 사용하여 작성토록 하겠다.
BigInteger프로젝트를 만들면서 이미 BigInt를 하위프로젝트로 삽입했고, BigInt솔루션이 DLL을 생성하도록 해놨다. (이 부분은 이번 장 앞부분에서 이미 설명되어 있음)
이 BigInt.dll을 사용하는 기본 구조는 다음과 같다.
using System.Runtime.InteropServices;
[DllImport("BigInt.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int compare_big(UInt32[] a, UInt32[] b);
public bool isEqual(BigInteger b)
{
......
if (compare_big(this.data, b.data) == 0) return true;
......
}
DllImport구문을 사용하기 위해서는 using구문의 명시되어 있어야한다.
- using 구문 정의: using System.Runtime.InteropServices
DllImport구문에 DLL파일명을 적고, 호출규약을 명시한다. 이 호출 규약은 BigInt.dll을 생성하는 프로젝트에서 "구성 - 구성속성 - C/C++ - 고급"에 있는 "호출 규칙"에서 정할 수 있고, 3가지의 호출 규칙을 선택할 수 있는데, 이미 BigInt프로젝트에서는 _cdecl(/Gd)로 호출되어 있도록 설정해놨기에, C#에서 BigInt.dll을 import할 때 CallingConvention으로 Cdecl로 해주는 것이다.
위 예에서는 C로 작성된 compare_big함수를 호출하는 것인데,
__declspec(dllexport) int compare_big(BIGINT a, BIGINT b);
private static extern을 붙여주고, return 형식과 함수명, 그리고 파라미터를 적어주면 된다.
private static extern int compare_big(UInt32[] a, UInt32[] b);
접근 한정자는 private으로 했다. public으로 해도 무방하나, private으로 해서 클래스 내부의 메서드에서만 가능하도록 하고, 클래스내에 별도의 public 메서드를 만들어서, 이 public 메서드내에서만 dll함수를 접근하는 형태로 설계했다.
데이터 형 변환
C로 되어 있는 함수를 C#에서 호출 할 때 가장 신경쓰이는 부분이 변수형을 맞추는 것이다. 서로 사용되는 변수와 할당되는 메모리 크기가 다를 수 있고, C에서는 포인터가 지원되는데 C#에서는 안되는 부분 등이 있어서 그렇다.
그렇지만, 아래 표대로 변환을 해 준다면 그리 어려운 일도 아니다.
C | 크기[bytes] | C# |
bool | 1 | int |
char | 1 | char |
unsigned char | 1 | byte |
short | 2 | short |
unsigned short | 2 | ushort |
int | 4 | int |
unsigned int | 4 | uint |
long | 4 | int |
unsigned long | 4 | uint |
float | 4 | float |
double | 8 | double |
int[] | int[] | |
int * | int[] | |
unsigned int[] | uint[] | |
unsigned int* | uint[] | |
char*, LPSTR | string | |
BSTR | string | |
const char* | string | |
unsigned char* | byte[] | |
HANDLE, void* | IntPtr | |
VARIANT | object |
위 규칙에 따라 BIGINT관련되어 C#에서 사용될 수 있게 될 C함수 리스는 아래와 같다. (bigint.h에 정의)
__declspec(dllexport) int compare_big(BIGINT a, BIGINT b); __declspec(dllexport) int increse(BIGINT A); __declspec(dllexport) int negative(BIGINT A); __declspec(dllexport) int positive(BIGINT A); __declspec(dllexport) int hexstr2bigint(char* str, BIGINT a); __declspec(dllexport) int hexstr2bytes(char* str, unsigned char* a); __declspec(dllexport) int bytes2bigint(unsigned char* c, unsigned short bytesLen, BIGINT a); __declspec(dllexport) char* bigint2hexstr(BIGINT a); __declspec(dllexport) unsigned char * bigint2bytes(BIGINT a); __declspec(dllexport) void setmax(BIGINT a); __declspec(dllexport) int abs(BIGINT); __declspec(dllexport) void copy_big(BIGINT tgt,BIGINT src); __declspec(dllexport) int add(BIGINT A, BIGINT B, BIGINT C); __declspec(dllexport) int subtract(BIGINT A, BIGINT B, BIGINT C); __declspec(dllexport) int decrese(BIGINT A); __declspec(dllexport) int multiply(BIGINT A, BIGINT B, BIGINT C); __declspec(dllexport) int square(BIGINT A, BIGINT C); __declspec(dllexport) int divide(BIGINT A, BIGINT B, BIGINT Q, BIGINT R); __declspec(dllexport) int power(BIGINT A, u32 n, BIGINT C); __declspec(dllexport) int mod(BIGINT A, BIGINT B, BIGINT R); __declspec(dllexport) int mod_add(BIGINT A, BIGINT B, BIGINT N, BIGINT R); __declspec(dllexport) int mod_subtract(BIGINT A, BIGINT B, BIGINT N, BIGINT R); __declspec(dllexport) int mod_square(BIGINT A, BIGINT N, BIGINT R); __declspec(dllexport) int mod_multiply(BIGINT A, BIGINT B, BIGINT N, BIGINT R); __declspec(dllexport) int mod_exp(BIGINT A, BIGINT E, BIGINT N, BIGINT R); __declspec(dllexport) int gcd(BIGINT A, BIGINT B, BIGINT C); __declspec(dllexport) int bit_and(BIGINT A, BIGINT B, BIGINT C); __declspec(dllexport) int bit_or(BIGINT A, BIGINT B, BIGINT C); __declspec(dllexport) int bit_xor(BIGINT A, BIGINT B, BIGINT C); __declspec(dllexport) int shiftleft_INT(BIGINT A, int n); __declspec(dllexport) int shiftright_INT(BIGINT A, int n); __declspec(dllexport) int shiftleft(BIGINT A, int n); __declspec(dllexport) int shiftright(BIGINT A, int n); __declspec(dllexport) int bit_count(BIGINT A); __declspec(dllexport) int bit_length(BIGINT); __declspec(dllexport) char *convert_digit(BIGINT A, u8 radix, int *returnCode); __declspec(dllexport) int generate_random(BIGINT A, int bitsCount); __declspec(dllexport) int rabin_miller(BIGINT N, int k, int *returnCode);
'암호화프로그래밍 > C#-BigInteger' 카테고리의 다른 글
006. BigInteger 코딩 - Type Casting (0) | 2013.10.18 |
---|---|
005. BigInteger 코딩 - 메서드 (0) | 2013.10.18 |
003. BigInteger 코딩 - 상수, 변수, 생성자 (0) | 2013.10.18 |
002. BigInteger 클래스 설계 (0) | 2013.10.18 |
001. BigInteger 라이브러리 작성을 위한 프로젝트 생성 (0) | 2013.10.17 |