GMPライブラリのMPIRの使用について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
YEP

GMPライブラリのMPIRの使用について

#1

投稿記事 by YEP » 10年前

はじめまして、最近プログラムの学習を始めました
多倍長整数を扱う上でGMPライブラリが必要になったので、それのwindowsに簡易版としてだされているMPIRを使いたいと思いました。
自分なりに調べてやったのですがインクルードまではできますがその後関数を使用しようとするとLNK2019エラーが出てしまいます。
以下に自分がやった手順を書きますので、間違っている部分や正しいやり方を教えてください。
環境はVisual C++ 2010にMPIR2.60を使用しようとしています。

1.MPIR2.60をダウンロード
2.\mpir-2.6.0\build.vc10にあるmpir.slnを起動
3.dll_mpir_gcを右クリックでビルド
4.mpir.hは\mpir-2.6.0にあるのでインクルードディレクトリとして指定
5.\mpir-2.6.0\build.vc10\Win32\Debugにmpir.libやmpirxx.libがあるのでライブラリディレクトリとして指定

講義等まだ無く、参考書やネット片手の独学ですので色々と拙い部分が非常に多いと思いますが、どうかよろしくお願いします

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: GMPライブラリのMPIRの使用について

#2

投稿記事 by みけCAT » 10年前

YEP さんが書きました:5.\mpir-2.6.0\build.vc10\Win32\Debugにmpir.libやmpirxx.libがあるのでライブラリディレクトリとして指定
プロジェクトの設定か何かで、ライブラリをリンクするように設定しましたか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

YEP

Re: GMPライブラリのMPIRの使用について

#3

投稿記事 by YEP » 10年前

みけCAT さんが書きました:
YEP さんが書きました:5.\mpir-2.6.0\build.vc10\Win32\Debugにmpir.libやmpirxx.libがあるのでライブラリディレクトリとして指定
プロジェクトの設定か何かで、ライブラリをリンクするように設定しましたか?
はい、メニュー>プロジェクト>プロジェクトのプロパティ>構成プロパティ>VC++ディレクトリ、よりライブラリディレクトリにパスを追加しました

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: GMPライブラリのMPIRの使用について

#4

投稿記事 by みけCAT » 10年前

GCCを使ったほうが簡単だと思います。
1. GCC(G++を含む)をダウンロードし、適当なディレクトリに展開してパスを通す
2. MSYSをインストールする
3. MPIR - Homeからmpir-2.6.0.tar.bz2をダウンロードし、解凍する
4. 解凍したディレクトリにMSYSのシェルで移動し、

コード:

$ ABI=32 ./configure --prefix=(ライブラリを置きたいディレクトリ)
$ make -j 4
$ make install
5. 適当なコードを書き、コンパイルする

コード:

g++ -O2 -s -static -o testcode testcode.cpp -I(上記prefixで指定したディレクトリ)\include -L(上記prefixで指定したディレクトリ)\lib -lmpir
テストに使用したコード(testcode.cpp)
ちょうど他の人がハッシュ値の文字列表現の入力を質問していたので、そのコードを試してみました。

コード:

#include <cstdio>
#include <cstring>
#include <string>
#include <mpir.h>

#define SHR(n,x) ((x)>>(n))
#define ROTR(n,x) ( ((x)>>(n)) | ((x)<<(32-(n))) )

#define Ch(x,y,z) ( ((x)&(y)) ^ ((~(x))&(z)) )
#define Maj(x,y,z) ( ((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)) )
#define Sigma0(x) ( ROTR(2,x) ^ ROTR(13,x) ^ ROTR(22,x) )
#define Sigma1(x) ( ROTR(6,x) ^ ROTR(11,x) ^ ROTR(25,x) )
#define Ro0(x) ( ROTR(7,x) ^ ROTR(18,x) ^ SHR(3,x) )
#define Ro1(x) ( ROTR(17,x) ^ ROTR(19,x) ^ SHR(10,x) )

static const unsigned int K[64]={
	0x428a2f98u,0x71374491u,0xb5c0fbcfu,0xe9b5dba5u,
	0x3956c25bu,0x59f111f1u,0x923f82a4u,0xab1c5ed5u,
	0xd807aa98u,0x12835b01u,0x243185beu,0x550c7dc3u,
	0x72be5d74u,0x80deb1feu,0x9bdc06a7u,0xc19bf174u,
	0xe49b69c1u,0xefbe4786u,0x0fc19dc6u,0x240ca1ccu,
	0x2de92c6fu,0x4a7484aau,0x5cb0a9dcu,0x76f988dau,
	0x983e5152u,0xa831c66du,0xb00327c8u,0xbf597fc7u,
	0xc6e00bf3u,0xd5a79147u,0x06ca6351u,0x14292967u,
	0x27b70a85u,0x2e1b2138u,0x4d2c6dfcu,0x53380d13u,
	0x650a7354u,0x766a0abbu,0x81c2c92eu,0x92722c85u,
	0xa2bfe8a1u,0xa81a664bu,0xc24b8b70u,0xc76c51a3u,
	0xd192e819u,0xd6990624u,0xf40e3585u,0x106aa070u,
	0x19a4c116u,0x1e376c08u,0x2748774cu,0x34b0bcb5u,
	0x391c0cb3u,0x4ed8aa4au,0x5b9cca4fu,0x682e6ff3u,
	0x748f82eeu,0x78a5636fu,0x84c87814u,0x8cc70208u,
	0x90befffau,0xa4506cebu,0xbef9a3f7u,0xc67178f2u
};

static unsigned int H[8];
static unsigned int sizeh,sizel;

void sha256init(void) {
	H[0]=0x6a09e667u;
	H[1]=0xbb67ae85u;
	H[2]=0x3c6ef372u;
	H[3]=0xa54ff53au;
	H[4]=0x510e527fu;
	H[5]=0x9b05688cu;
	H[6]=0x1f83d9abu;
	H[7]=0x5be0cd19u;
	sizeh=sizel=0;
}

static void sha256addOneDataBlock(const unsigned char* data) {
	unsigned int W[64];
	unsigned int a,b,c,d,e,f,g,h,T1,T2;
	int i;
	for(i=0;i<16;i++) {
		W[i]=(data[(i<<2)]<<24)|(data[(i<<2)|1]<<16)|
			(data[(i<<2)|2]<<8)|data[(i<<2)|3];
	}
	for(i=16;i<64;i++) {
		W[i]=Ro1(W[i-2])+W[i-7]+Ro0(W[i-15])+W[i-16];
	}
	a=H[0];b=H[1];c=H[2];d=H[3];
	e=H[4];f=H[5];g=H[6];h=H[7];
	for(i=0;i<64;i++) {
		T1=h+Sigma1(e)+Ch(e,f,g)+K[i]+W[i];
		T2=Sigma0(a)+Maj(a,b,c);
		h=g;g=f;f=e;
		e=d+T1;
		d=c;c=b;b=a;
		a=T1+T2;
	}
	H[0]+=a;H[1]+=b;H[2]+=c;H[3]+=d;
	H[4]+=e;H[5]+=f;H[6]+=g;H[7]+=h;
}

void sha256addData(const void* data,int dataSize) {
	int i;
	unsigned char* now=(unsigned char*)data;
	for(i=0;i<dataSize;i+=64) {
		sha256addOneDataBlock(now);
		now+=64;
	}
	sizel+=dataSize;
	sizeh+=(sizel>>29);
	sizel&=0x1fffffffu;
}

void sha256finish(unsigned char* sha256,const void* data,int dataSize) {
	int i;
	int leftLen;
	unsigned char* leftPtr;
	unsigned char buffer[64]={0};
	sha256addData(data,dataSize&(~63));
	leftLen=dataSize&63;
	leftPtr=((unsigned char*)data)+(dataSize&(~63));
	for(i=0;i<leftLen;i++) {
		buffer[i]=leftPtr[i];
	}
	buffer[i++]=0x80;/* leftLen<=63 */
	sizel+=leftLen;
	sizeh+=(sizel>>29);
	sizel&=0x1fffffff;
	sizel<<=3;
	if(leftLen<56) {
		buffer[56]=(sizeh>>24)&0xff;
		buffer[57]=(sizeh>>16)&0xff;
		buffer[58]=(sizeh>>8)&0xff;
		buffer[59]=sizeh&0xff;
		buffer[60]=(sizel>>24)&0xff;
		buffer[61]=(sizel>>16)&0xff;
		buffer[62]=(sizel>>8)&0xff;
		buffer[63]=sizel&0xff;
		sha256addOneDataBlock(buffer);
	} else {
		sha256addOneDataBlock(buffer);
		for(i=0;i<56;i++)buffer[i]=0;
		buffer[56]=(sizeh>>24)&0xff;
		buffer[57]=(sizeh>>16)&0xff;
		buffer[58]=(sizeh>>8)&0xff;
		buffer[59]=sizeh&0xff;
		buffer[60]=(sizel>>24)&0xff;
		buffer[61]=(sizel>>16)&0xff;
		buffer[62]=(sizel>>8)&0xff;
		buffer[63]=sizel&0xff;
		sha256addOneDataBlock(buffer);
	}
	for(i=0;i<32;i++) {
		sha256[i]=(H[i>>2]>>(8*(3-(i&3))))&0xff;
	}
}

std::string getSHA256(const unsigned char *data, int data_length) {
	unsigned char sha256[32];
	char buffer[128];
	std::string res = "";
	sha256init();
	sha256finish(sha256, data, data_length);
	for (int i = 0; i < 32; i++) {
		sprintf(buffer, "%02X", sha256[i]);
		res += buffer;
	}
	return res;
}

int main(void) {
	const char data_to_hash[] = "VC-WA-OMOKUTE-TUKAINIKUI-(KOZINNO-KANNSOU-DESU)";
	mpz_t integer;
	std::string hash;
	hash = getSHA256((unsigned char *) data_to_hash, strlen(data_to_hash));
	mpz_init(integer);
	mpz_set_str(integer, hash.c_str(), 16);
	mpz_out_str(stdout, 10, integer);
	mpz_clear(integer);
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

YEP

Re: GMPライブラリのMPIRの使用について

#5

投稿記事 by YEP » 10年前

ありがとうございます
この方法で試してみます

ISLe()

Re: GMPライブラリのMPIRの使用について

#6

投稿記事 by ISLe() » 10年前

ライブラリパスはライブラリファイルの在処を示すものです。
別の場所に移動されても良いように。

それとは別にリンクするライブラリファイルの名前を指定しなければいけません。

#gccで、-Lオプションでライブラリパスを指定し、-lオプションでリンクするライブラリを指定するのも同じことです。

VC++では

プロジェクトのプロパティの構成プロパティで『リンカー』→『入力』→『追加の依存ファイル』でリンクするライブラリファイルを指定する

あるいは

ライブラリファイルをリンクする必要のあるソースファイルに、
#pragma comment(lib, "mpir")
というふうにライブラリをリンクするオプションを埋め込む指定のコードを書く

という方法があります。

YEP

Re: GMPライブラリのMPIRの使用について

#7

投稿記事 by YEP » 10年前

お久しぶりです
この三連休でプログラミングの学習も大分すすみました
みけCATさんがおっしゃられた方法もできましたが、ISLe()さんがいったように自分の元のやり方だと依存ファイルの指定がされていないため関数が読み込まれなかったみたいです、どうも初歩的なミスのようでお恥ずかしい限りです
助言してくださったお二方につきましては、本当に助けになりました、ありがとうございました

閉鎖

“C言語何でも質問掲示板” へ戻る