Windowsプラットフォームの下でLiunxをシミュレートしてGCC環境を使ってCのSOライブラリをコンパイルします.

6584 ワード

Liunxの下にあるファイル:
.oは、Windowsに相当するターゲットファイルです.objファイルsoは共有ライブラリでありshared objectであり、動的接続に用いるものであり、dllとの差は少ない.aは静的ライブラリであり、複数である.oを合わせる、静的接続に用いる.La libtoolのために自動的に生成された共有ライブラリ、vi編集表示
 
まずVS 2008を開いてwin 32コンソールプロジェクトを新規作成し、次に2つのファイル(mathunits.hとmathunits.c)を新規作成します.
mathunits.h
#ifndef MATHUNITS_H
#define MATHUNITS_H

int add(int a,int b);
int sub(int x,int y);
void WriteSysLog(char *str);

#endif

mathunits.c
#include "mathunits.h"
#include "time.h"
#include "stdio.h"
#include "stdlib.h"


int add(int a,int b)
{
	return a + b;
}

int sub(int a,int b)
{
	return a - b;
}

void WriteSysLog(char *str)
{
	char buf[512];
	long MAXLEN = 10*1024*1024;//10MB
	time_t timep; 
	FILE *fp = NULL;
	struct tm *p; 

	time(&timep); 
	p = localtime(&timep); 
	memset(buf,0,sizeof(buf));
	sprintf(buf,"%d-%d-%d %d:%d:%d : ",(1900+p->tm_year),(1+p->tm_mon),\
		p->tm_mday,p->tm_hour, p->tm_min, p->tm_sec); //  p->tm_wday
	strcat(buf,str);
	strcat(buf,"\r
"); fp = fopen("./syslog.log","r"); if(fp==NULL) { fp = fopen("./syslog.log","w+"); } else { fseek(fp,0,2); if(ftell(fp) >= MAXLEN) { fclose(fp); fp = fopen("./syslog.log","w+"); // 10MB } else { fclose(fp); fp = fopen("./syslog.log","a"); } } fwrite(buf,1,strlen(buf),fp); fflush(fp); //fsync(fileno(fp)); fclose(fp); }

次に、メイン関数でテストを行います.(注:これはVS 2008環境でのmainです)
#include "stdafx.h"
#include "stdlib.h"
#include "mathunits.h"


int _tmain(int argc, _TCHAR* argv[])
{
	int c = add(7,9);

	printf("c = %d
",c); c = sub(8,19); printf("c = %d
",c); WriteSysLog("test log out."); system("pause"); return 0; }

コンパイルする前に、VS 2008の構成をCのコンパイルに設定することを忘れないでください.
1、C/C++のコンパイルの衝突が発生しないように、まずプレコンパイルヘッドを閉じます:プロジェクトの上で右建--"属性--"配置属性--"C/C++--"プレコンパイルヘッドを使用しないように設定します.
2、Cコードにコンパイルするように設定します.プロジェクトの上で右建--』属性--』配置属性--』C/C++--』高級--』は--にコンパイルしてCコード(/TC)にコンパイルする
以上が完了したら、VSの下でコンパイルして問題があるかどうかを確認できます.問題があったら自分でバグを処理してください.問題なければOKです.
 
以下、GCCを使用してコンパイルします.
(mathunits.hとmathunits.c)を簡単なディレクトリにコピーします.ここではF:SOで説明します.これは必須ではありません.ファイルを移動しなくてもいいです.
CygWinを実行します.bat、コマンドラインが空になります
コンパイルパスを設定.h和.cのパス(F:so)
cd/cygdrive/f/soリターンを入力
次に.cファイルは.oファイル、さらにoファイルで静的ライブラリ(.a)ファイルにコンパイル
gcc -c mathunits.c車に戻り、lsコマンドを使用してコンパイルされたファイルを表示できます.
画像の中にはlsの後ろにcmainがある警告もあります.cこれらは先に無視して、警告は私のcコードの中でいくつかの古いインタフェースの関数を使ったためです.そしてcmain.cは私がf:soに予め置いたmainテストファイルで、後で使います.
cmain.c
#include "stdio.h"
#include "mathunits.h"

int main(int agrc,char *argv){
 int c = add(7,9);

	printf("c = %d
",c); c = sub(8,19); printf("c = %d
",c); WriteSysLog("ok,good"); return 0; }

再将oファイルは.a静的ライブラリファイル.
ar -crv libunits.a mathunits.o
説明:libunitsは自己命名で、libを接頭辞とします.
a:ライブラリ名フォーマットlib.a、例えばlibmytest.a     
b:arコマンド静的ライブラリファイルd---指定された静的ライブラリファイルからファイルmを削除---指定された静的ライブラリファイルにファイルを移動するp---静的ライブラリファイルで指定されたファイルを標準出力qに出力---静的ライブラリファイルにファイルをすばやく追加するr---静的ライブラリファイルにファイルを挿入するt---静的ライブラリファイルのファイルのリストxを表示する------静的ライブラリファイルからファイルを抽出
 
Arコマンドのコマンドライン形式は、ar[-]{dmpqrtx}[abcfilNoPsSubV][membername][count]archive files...パラメータarchiveはライブラリの名前を定義します.filesはライブラリファイルに含まれるターゲットファイルのリストで、各ファイルをスペースで区切ります.
次に、静的ライブラリの使用をテストし、前のcmailをテストします.cはf:soディレクトリの下に置きます.
GCCでスタティックライブラリの接続使用を行います.
コマンド:
方法1:
gcc  -o testlib cmain.c -L. -lunits
説明:testlibは最終的にコンパイルされたEXEファイル名です.-L.現在のパスを検索する(.)を選択します.aファイル、すなわち、現在のディレクトリで接続ライブラリを検索することを示す.
-lunitsではunitsがライブラリの名前でlib接頭辞が削除されています.
-l:コンパイラは動的接続ライブラリを検索する際に暗黙の命名規則がある、すなわち与えられた名前の前にlibを付け、後に付ける.soはライブラリの名前を決定し、静的ライブラリであれば後に付ける.aで名前を決定する.
出力testlibを実行します.exe
コマンドを入力:
./testlibリターン
静的ライブラリが使用中に正常に(EXEにリンクされている)プログラムに組み込まれていることを確認します.libunitsを削除します.aファイルを実行してから実行します./testlib.
正常に出力された場合は、成功したコレクションを示します.
 
静的ライブラリで使用する方法2:
gcc cmain.c libunits.a -o testlib
方法3:まずcmain.c生成oファイル、実行可能ファイルを再生成します.
gcc  -c cmain.c//生成.o
gcc  -o testlib cmain.o  libunits.a
 
以上が生成静的ライブラリである.aファイル.
次に、ダイナミックライブラリを生成する.soファイル.
あります.oファイルの後でsoを打つことができます.
コマンド:
gcc  -shared -fPCI -o libdyunits.so mathunits.o
そのうち-oは少なくない.
-sharedこのオプションは、外部プログラムが接続できないことを示す動的接続ライブラリの生成を指定します(コネクタにTタイプのエクスポートシンボルテーブルを生成させ、弱い接続Wタイプのエクスポートシンボルを生成させる場合もあります).実行可能ファイル-fPICに相当するのは、コンパイルが位置独立のコードであることを示し、このオプションを使用しないとコンパイルされたコードは位置依存であるため、動的ロード時にコードコピーによって異なるプロセスのニーズを満たし、真のコードセグメント共有の目的を達成することはできない.
-L.接続するライブラリが現在のディレクトリにあることを示します.(複数のライブラリ:コンパイルコマンドラインでは、使用する静的ライブラリファイルをソースファイルの後ろに置けばよい.たとえば、gcc-L/usr/lib myprop.c libtest.a libX 11.a libpthread.a-o mypropでは、-L/usr/libがライブラリファイルの検索パスを指定します.コンパイラは、前の「法二#gcc cmain.c libunits.a-o testlib」のように、現在のディレクトリの下で指定したライブラリファイルをデフォルトで検索します)
LD_LIBRARY_PATHという環境変数は動的コネクタが動的ライブラリをマウントできる経路を示す.もちろんroot権限があれば/etc/ldを変更できます.so.confファイルは、/sbin/ldconfigを呼び出して同じ目的を達成しますが、root権限がない場合は、出力LD_しか使用できません.LIBRARY_PATHの方法です.
ダイナミックライブラリを呼び出すときにいくつかの問題が発生することがあります.時には、ライブラリのヘッダファイルが存在するディレクトリが「-I」includeを介して入ってきたのに、ライブラリが存在するファイルが「-L」パラメータで案内され、「-l」のライブラリ名が指定されているのに、lddコマンドで確認すると、リンクを指定したsoファイルが見つからず、LD_を変更する必要があります.LIBRARY_PATHまたは/etc/ld.so.confファイルは、ダイナミックライブラリのディレクトリを指定します.通常は、ライブラリがリンクできない問題を解決できます.
追加:
上記から、生成されたダイナミックライブラリをどのように見つけるかには、次の3つの方法があります.
(1)ライブラリを/usr/libおよび/libディレクトリにコピーする.
(2)LD_LIBRARY_PATH環境変数にライブラリが存在するパスを追加します.
例えばダイナミックライブラリlibhello.soは/home/example/libディレクトリの下にあります.
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/example/lib
(3)修正/etc/ld.so.confファイルは、ライブラリが存在するパスをファイルの最後に追加し、ldconfigリフレッシュを実行します.これにより、追加したディレクトリの下にあるすべてのライブラリファイルが表示されます.
 
ダイナミックライブラリの接続使用は、静的ライブラリ使用コマンドと同様に、静的ライブラリとダイナミックライブラリが同時に存在する場合は、ダイナミックライブラリを優先的に呼び出します.
gcc cmain.c libdyunits.so -o testlib
 
次のコマンドを使用するときにエラーが発生し、弟は解決できませんでした.いくつかのネット上の解決策を試しても解除できません.
パス設定の問題が発生しました.
1:unix/linux環境で1.1:生成.oファイルgcc-I/usr/lib/j 2 sdk 1.5-ibm/include -fPIC -c example.c 1.2:ダイナミックライブラリを生成する.soファイルgcc-shared-WI-soname example.o -o  libexample.so 2:windows環境で2.1:生成.oファイルgcc-c-I"D:Program FilesJavajdk 1.6.0_10include"-I"D:Program FilesJavajdk 1.6.0_10includewin 32"-o Hello.o Hello.c 2.2:dllファイルgcc-I"D:Program FilesJavajdk 1.6.0_10include"-Wl,--add-stdcall-alias-shared-o Helloを生成する.dll Hello.o