ダートは、Cプログラミング言語のミックスを呼び出します

ダートは、C言語を呼び出す
Cコードのハイブリッドプログラミングを呼び出す方法をこのブログダート語学簡単な例を達成するため、我々は最終的には、C言語、ダーツコールの使用に簡単な暗号化と復号化関数を記述し、文字列を渡すと、暗号化の結果を返し、復号化コールこの関数は、文字列の内容を復元します。

環境準備
コンパイラ環境
GCC VSコンパイラインストールされていない、Windowsの64ビット版をダウンロードし、GCCコンパイラを使用することを推奨されている場合- MinGWの-W64を
ダウンロード


上記のように、それは二つのバージョン、sjljと接尾SEH例外処理モデル、SEH良好な性能を持っていますが、32ビットをサポートしていません。Sjlj良好な安定性、32ビットのサポート、SEHのバージョンをお勧めします

コンパイラは、インストール後に、また、環境変数を設定する必要があり、指定したディレクトリにマウントされ、システムのインストールbinディレクトリがgcc.exeを備え、PATH環境変数に追加され、チェーンのbinディレクトリのようMAKE.EXEツール。

テスト環境
設定、環境が成功し、オープンのcmdコマンドラインを構築するかどうかを確認するためのテスト、型はgcc -vした後は、数が成功したバージョンを確認することができます。

ダートSDK環境は、
以前のバージョンは、FFIダウンロードをサポートしていないことに注意して、SDKの最新バージョン2.3をダウンロードするにはダート公式サイトを運命づけ

ダウンロードした後、あなたはまた、環境変数、システムのPATH環境変数に設定さダーツ-SDKの\ビンを設定する必要があります。

ダーツFFIテストインタフェース
の簡単な例を
テストプロジェクトを作成、オープンCMDコマンドライン

FFI-PROJは、mkdir
CD FFI-PROJの
は、mkdirビンSRC
1
2
3
SRCのtest.cの中にファイルを作成し、ビンにmain.dartファイルを作成し、srcフォルダ、その下のビンを作成し、プロジェクトディレクトリFFI-PROJを作成します。

書き込みtest.cの
、showBox機能用の窓が含まれているヘッダファイルで私たちをのWin32 APIを呼び出して、ダイアログボックスを作成します

書式#include <WINDOWS.H>

INT(INT A、INT B){追加
、+ Bを返します
}


showBox(){VOID
メッセージボックスは、(NULL、 "ハローダート"は、 "タイトル"、MB_OK);
}
。1
2
3
4
5
6
7
8
9
10
GCCコンパイラを使用してsrcディレクトリには、C言語コードは、DLL動的にコンパイル倉庫

-shared -o Test.dllのtest.cのgccの
1個の
書き込みmain.dart

インポート:FFIとして'ダーツFFI';
インポート'ダーツ:IO'は、show platform;

///メソッドシグネチャで定義された関数C(呼び出されたメソッドのシグネチャは、メソッドまたは関数が戻り値の型、パラメータの型を含む、記載される)
署名は2つのメソッドを定義する必要が///、言語はCでありますDARTに変換した後1つに
; typedefのNativeAddSign = ffi.Int32機能(ffi.Int32、ffi.Int32)
のtypedef int型DartAddSign機能=(INT、int)を、

/// showBoxメソッドシグネチャ関数
のtypedef NativeShowSign = ffi.Void機能();
typedefの空隙DartShowSign =関数()。

ボイドメイン(リストの<string>引数){
IF(Platform.isWindows){
//加载DLL动态库
ffi.DynamicLibrary DL = ffi.DynamicLibrary.open( "../ SRC / TEST.DLL")。

// lookupFunctionは、指定された動的ライブラリ関数を見出すために、二つの機能、一つを有する; 2、ネイティブタイプCの機能をダート関数型に
VAR追加= dl.lookupFunction <NativeAddSign、DartAddSign >(「追加します」)。
VaRのshowBox = dl.lookupFunction <NativeShowSign、DartShowSign >( "showBox");

//関数呼び出し追加
印刷((追加8 ,. 9)。);
//関数showBox呼び出し
showBoxを();
}
}
。1
2
3。
4。
5。
6。
7。
8。
9。
10
11
12である
13である
14
15
16
17
18である
19。
20
21である
22である
23であり、
24
25
26
27


で、深さの使用
ここでは、少し他の例を記述するために、我々は、C言語で簡単な暗号化アルゴリズムを記述し、その後、ダーツ呼び出しC関数の暗号化と復号化を使用します

シンプルなXOR暗号化アルゴリズム、暗号化と復号化を記述するためにここに、encrypt_test.cを書くすることは実質的に同一見ることができます

#include <string.hの>

の#define KEY 'ABC'

ボイド暗号化(チャー* STR、CHAR * R、INT r_len){
int型LEN = STRLEN(STR)。
(I 0 = int型私は++; iはr_len <&& lenの<)のために{
R [I] = STR [I] ^ KEY。
}

IF(r_len> LEN)R [LEN] = '\ 0'。
他のR [r_len] = '\ 0';

}

ボイド解読(チャー* STR、CHAR * R、INT r_len){
int型LEN = STRLEN(STR)。
(I 0 = int型私は++; iはr_len <&& lenの<)のために{
R [I] = STR [I] ^ KEY。
}

(r_len> LEN)R&LT [LEN] = '\ 0' IF;
他のR&LT [r_len] = '\ 0';
}
1
2
3。
4。
5。
6。
7。
8。
9。
10
11
12である
13である
14
15
16
17
18れている
19。
20
21であり、
22は
23
24
動的ライブラリにコンパイル

gccのencrypt_test.c -shared -o encrypt_test.dll
1
编写main.dart

インポート'ダーツ:FFI';
インポート'ダーツ:IO'は、show platform;
インポート「ダーツ:変換します」;


///暗号化関数のメソッドシグネチャは、関数の戻り値とパラメータのタイプの2種類が同一である方法は、暗号化し、ここで署名を復号化することは、実際には同じである留意
NativeEncrypt =ボイド関数(のCString、CStringの、Int32)をtypedefは、
typedefをDartEncrypt =無効機能(のCString、CStringの、int型 );


ボイドメイン(リストの<string>引数){
IF(Platform.isWindows){
//加载DLL动态库
DynamicLibrary DL = DynamicLibrary.open( "../ SRC / encrypt_test.dll")。
VaRの暗号化= dl.lookupFunction <NativeEncrypt、DartEncrypt>( "暗号化")。
VaRの解読= dl.lookupFunction <NativeEncrypt、DartEncrypt>( "解読");


CStringのデータ= CString.allocate( "HelloWorldの")。
CStringのenResult = CString.malloc(100)。
暗号化(データ、enResult、100)。
プリント(CString.fromUtf8(enResult))。

印刷( "-------------------------");

CStringのdeResult = CString.malloc(100)。
解読(enResult、deResult、100)。
プリント(CString.fromUtf8(deResult))。
}
}

///、ポインタ<INT8>ポインタを継承するクラスを作成するC言語の文字列をマッピングするための処理とDART文字列にする
クラスのCStringは、ポインタ<INT8>を{延び

///アプリケーションのメモリ空間、ストリングダートにC言語の文字列
工場CString.allocate(文字列dartStr){
リスト<整数>単位= Utf8Encoder()変換(dartStr);.
ポインタ<INT8> = STR(COUNTを割り当てます:+ units.length 1);
Iはunits.lengthを<; Iは++){(I = 0 int型ため
str.elementAt(I).store(単位[I]);
}
str.elementAt(units.length) .store(0)。

str.cast返します();
}

//アプリケーション・ヒープメモリ空間指定されたサイズの
工場CString.malloc(int型のサイズ){
ポインタ<INT8> = STR(カウント:サイズ)を割り当て、
戻りstr.cast();
}

///文字列ダートにC言語の文字列
静的な文字列fromUtf8(CStringのSTR){
IF(STR == NULL)戻りNULL;
INT LEN = 0;
一方(str.elementAt(++ LEN) .LOAD <整数>()= 0);!
一覧<整数>リスト単位=(LEN)
のための(INT I = 0; IがLEN <; I ++の)単位[I] = str.elementAt(I)。負荷();
戻りUtf8Decoder();.(単位)変換
}
}
。1
2
3
4
5
6
7
8
9
10
11
12である
13である
14
15
16
17
18である
19。
20
21である
22である
23である
24
25
26である
27
28
29
30
31は、
32
33である
34である
35
36
[37
38である
39
40
41である
42は
43である
44は
45
46である
47
48
49
50
51である
52は
53である
ている54
55
56が
57である
58
59
60
61のれている
62である
実行結果

あなたは後のコンテンツを復元する復号化文字列、文字化けした文字列の暗号化の束になって「HelloWorldの」を参照してくださいすることができます

コードの改善
上記のコードをしかし私たちの目標を達成したが、明らかなメモリリークがあり、我々はmalloc関数を使用してアプリケーション・ヒープ・メモリのCStringのを割り当てるが、ないマニュアルリリースがありません、あなたはしばらくの間、この操作後のメモリ領域が不足して、手動で管理メモリは、多くの場合、我々はメモリを再利用するためにシンプルなデザインを行なうことができる最も問題領域におけるC / C ++、あります

参考のCStringクラス追跡アプリケーションメモリ作成//
クラスリファレンス{
最終リスト<ポインタ<ボイド>> _allocations = [];

T refは<Tが延びポインタ>(TのPTR){
_allocations.add(ptr.cast())。
PTR返します。
}

使用メモリ後//手動解除
()ボイドファイナライズ{
(_allocationsで最終PTR)は{
ptr.free();
}
_allocations.clear();
}
}
。1
2
3。
4。
5。
6。
7。
8。
9。
10
11
12である
13であり、
14
15
16
。17
コードを変更します

インポート'ダーツ:FFI';
インポート'ダーツ:IO'は、show platform;
インポート「ダーツ:変換します」;


///暗号化関数のメソッドシグネチャは、関数の戻り値とパラメータのタイプの2種類が同一である方法は、暗号化し、ここで署名を復号化することは、実際には同じである留意
NativeEncrypt =ボイド関数(のCString、CStringの、Int32)をtypedefは、
typedefをDartEncrypt =無効機能(のCString、CStringの、int型 );


ボイドメイン(リストの<string>引数){
IF(Platform.isWindows){
//加载DLL动态库
DynamicLibrary DL = DynamicLibrary.open( "../ SRC / hello.dll")。
VaRの暗号化= dl.lookupFunction <NativeEncrypt、DartEncrypt>( "暗号化")。
VaRの解読= dl.lookupFunction <NativeEncrypt、DartEncrypt>( "解読");

//创建参考跟踪CStringの
基準REF =リファレンス();

CStringのデータ= CString.allocate( "HelloWorldの"、REF)。
CStringのenResult = CString.malloc(100、REF)。
暗号化(データ、enResult、100)。
プリント(CString.fromUtf8(enResult))。

印刷( "-------------------------");

CStringのdeResult = CString.malloc(100、REF)。
解読(enResult、deResult、100)。
プリント(CString.fromUtf8(deResult))。

使用後//手動解除
ref.finalize();
}
}

クラスのCStringは、ポインタを拡張<INT8> {

それが制御///メモリ、ストリングダートにC言語の文字列
工場CString.allocate(文字列dartStr、[REFリファレンス]){
一覧<整数>単位= Utf8Encoder()変換(dartStr);.
ポインタ<INT8> = STRを(COUNT:units.lengthの+ 1)を割り当てる;
{(; Iはunits.lengthを<I ++はI = 0をINT)ため
str.elementAt(I).store(単位[I]);
}
str.elementAt (units.length).store(0)。

REF .REF(STR);?
str.cast返します();
}

工場CString.malloc(int型のサイズ、[参考文献]){
ポインタ<INT8> STR =(カウント:サイズ)を割り当てます。
REF .REF(STR);?
str.cast返します();
}

///文字列ダートにC言語の文字列
静的な文字列fromUtf8(CStringのSTR){
IF(STR == NULL)戻りNULL;
INT LEN = 0;
一方(str.elementAt(++ LEN) .LOAD <整数>()= 0);!
一覧<整数>リスト単位=(LEN)
のための(INT I = 0; IがLEN <; I ++の)単位[I] = str.elementAt(I)。負荷();
戻りUtf8Decoder();.(単位)変換
}
}
。1
2
3
4
5
6
7
8
9
10
11
12である
13である
14
15
16
17
18である
19。
20
21である
22である
23である
24
25
26である
27
28
29
30
31は、
32
33である
34である
35
36
37
38である
39
40
41である
42は
43である
44は
45
46である
47
48
49
50
51である
52は
53である
ている54
55
56が
57である
58
59
60
61である
62は
63である
64
65
66
67
まとめ
一時的に解除FFIパケット現在処理中の開発:ダート唯一の基本的な機能、およびDARTの使用:FFIパッケージ後FFIインタフェースかのように、AOTダートコードをコンパイルすることはできないが、ダートを大幅言語の境界をDARTに機能を拡張し、FFIのインターフェイスを開発しただけのJava JNIとして開発は十分だった、ダートはPythonのような接着剤言語としての真なることができるようになります。

あなたはさらなる研究に興味があるなら、あなたはダーツ表示できますFFIのソースパッケージを、パッケージには、現在の学習に適した唯一の5ダーツファイル、ソースコードまれ、の合計です。
--------------------- 

おすすめ

転載: www.cnblogs.com/ly570/p/10942293.html