암호화프로그래밍/C#-BigInteger

004. BigInteger 코딩 - DLL호출 메서드

산을좋아한라쯔 2013. 10. 18. 16:49
반응형

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(dllexportint 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(dllexportint compare_big(BIGINT a, BIGINT b);
__declspec(dllexportint increse(BIGINT A);
__declspec(dllexportint negative(BIGINT A);
__declspec(dllexportint positive(BIGINT A);
__declspec(dllexportint hexstr2bigint(char* str, BIGINT a);
__declspec(dllexportint hexstr2bytes(char* str, unsigned char* a);
__declspec(dllexportint bytes2bigint(unsigned char* c, unsigned short bytesLen, BIGINT a);
__declspec(dllexportchar* bigint2hexstr(BIGINT a);
__declspec(dllexportunsigned char * bigint2bytes(BIGINT a);
__declspec(dllexportvoid setmax(BIGINT a);
__declspec(dllexportint abs(BIGINT);
__declspec(dllexportvoid copy_big(BIGINT tgt,BIGINT src);
__declspec(dllexportint add(BIGINT A, BIGINT B, BIGINT C);
__declspec(dllexportint subtract(BIGINT A, BIGINT B, BIGINT C);
__declspec(dllexportint decrese(BIGINT A);
__declspec(dllexportint multiply(BIGINT A, BIGINT B, BIGINT C);
__declspec(dllexportint square(BIGINT A, BIGINT C);
__declspec(dllexportint divide(BIGINT A, BIGINT B, BIGINT Q, BIGINT R);
__declspec(dllexportint power(BIGINT A, u32 n, BIGINT C);
__declspec(dllexportint mod(BIGINT A, BIGINT B, BIGINT R);
__declspec(dllexportint mod_add(BIGINT A, BIGINT B, BIGINT N, BIGINT R);
__declspec(dllexportint mod_subtract(BIGINT A, BIGINT B, BIGINT N, BIGINT R);
__declspec(dllexportint mod_square(BIGINT A, BIGINT N, BIGINT R);
__declspec(dllexportint mod_multiply(BIGINT A, BIGINT B, BIGINT N, BIGINT R);
__declspec(dllexportint mod_exp(BIGINT A, BIGINT E, BIGINT N, BIGINT R);
__declspec(dllexportint gcd(BIGINT A, BIGINT B, BIGINT C);
__declspec(dllexportint bit_and(BIGINT A, BIGINT B, BIGINT C);
__declspec(dllexportint bit_or(BIGINT A, BIGINT B, BIGINT C);
__declspec(dllexportint bit_xor(BIGINT A, BIGINT B, BIGINT C);
__declspec(dllexportint shiftleft_INT(BIGINT A, int n);
__declspec(dllexportint shiftright_INT(BIGINT A, int n);
__declspec(dllexportint shiftleft(BIGINT A, int n);
__declspec(dllexportint shiftright(BIGINT A, int n);
__declspec(dllexportint bit_count(BIGINT A);
__declspec(dllexportint bit_length(BIGINT);
__declspec(dllexportchar *convert_digit(BIGINT A, u8 radix, int *returnCode);
__declspec(dllexportint generate_random(BIGINT A, int bitsCount);
__declspec(dllexportint rabin_miller(BIGINT N, int k, int *returnCode);

 

 

 

반응형