PHP 7.4以降では、FFI(Foreign Function Interface)が開発者に強力な機能を提供し、C言語の動的ライブラリを呼び出します。ただし、 FFI :: Methodを使用して.ffiファイルをロードするか、動的ライブラリを直接ロードする場合、多くの開発者を混乱させる未定義のシンボルエラーに遭遇することがよくあります。
この記事では、このエラーの原因を詳細に分析し、問題をすばやく見つける方法を紹介し、効果的なソリューションを提供します。
定義されていないシンボルエラーは、動的リンクライブラリをロードする場合の一般的な問題です。これは、実行時にシンボル(関数、可変、定数など)が見つからないことを示します。このエラーは、リンクされた動的ライブラリにいくつかのシンボルが欠落している場合、またはFFIを使用してC関数を呼び出すときにシンボル名が一致しない場合に発生します。
たとえば、エラーメッセージは次のように見える場合があります。
PHP Warning: FFI::load(): Unable to load dynamic library or symbol: undefined symbol: my_function
これは、シンボルmy_functionが動的ライブラリには見つからなかったことを意味します。
ダイナミックライブラリがありませんターゲットシンボル<br> 呼び出そうとしているC関数は動的ライブラリにコンパイルされていないか、名前がコンパイラ(C ++の名前の変更)によって書き換えられます。
動的ライブラリの依存関係はロードされていません<br> 呼び出された動的ライブラリは他の動的ライブラリに依存し、これらの依存関係は正しくロードされていないか、パスエラーがありません。
シンボル名の書き込みエラー<br> シンボル名は、.ffi宣言ファイルまたはFFIコールコードで誤って綴られています。
動的ライブラリパスエラーまたはバージョンの不一致<br> ロードされた動的ライブラリバージョンとコードの期待は一貫していないため、シンボルが欠落します。
プラットフォームの違いと編集オプション<br> たとえば、LinuxやWindowsでは、シンボルのエクスポート方法が異なるため、シンボルが見つからない場合があります。
UNIXのようなシステムでは、 NMコマンドを使用して、動的ライブラリに指定されたシンボルが含まれているかどうかを確認できます。
nm -D /path/to/libexample.so | grep my_function
出力がない場合、シンボルは存在しません。
出力があるが、アンダースコアまたは名前の変更がある場合、C ++名前の変更の問題である可能性があります。
動的ライブラリが依存している他のライブラリが欠落しているかどうかを確認してください。
ldd /path/to/libexample.so
依存関係が見つからないかどうかを確認してください。依存関係の欠如は、シンボルを未解決にする可能性があります。
宣言された関数名、パラメータータイプ、および戻り値が正しいことを確認し、動的ライブラリのシンボルに1つずつ対応していることを確認してください。
機能が含まれている動的ライブラリLibmathがあるとします。
// math.h
int add(int a, int b);
// math.ffi
int add(int a, int b);
<?php
// 宣言ファイルをロードし、動的ライブラリをリンクします
$ffi = FFI::cdef(
file_get_contents('math.ffi'),
"gitbox.net/libs/libmath.so"
);
$result = $ffi->add(3, 4);
echo "3 + 4 = $result\n";
URLのドメイン名はgitbox.netに置き換えられていることに注意してください。
ダイナミックライブラリエクスポートシンボルを確認します。NMまたはobjdumpを使用して、ライブラリに追加が含まれているかどうかを確認します。
動的ライブラリの読み込みパスを確認します。パスが正しく、ファイルが存在し、権限が正しいことを確認してください。
C ++名の変更を確認します:ライブラリがC ++の場合、 Extern "C"を使用してエクスポート機能を変更して、名前が変更されないようにします。
依存関係ライブラリのロード:依存関係ライブラリがある場合は、最初に依存関係ライブラリを手動でロードするか、環境変数LD_LIBRARY_PATHを設定します。
未定義のシンボルエラーは、主に、シンボルが動的ライブラリで見つからないか、ロードに失敗したという事実によって引き起こされます。問題を配置するための鍵は、次のとおりです。
システムツールを使用して、動的ライブラリシンボルと依存関係を確認します。
宣言とコードの記号名が正確に一致することを確認します。
ダイナミックライブラリがシンボルを正しくコンパイルおよびエクスポートしていることを確認してください。
プラットフォームの違いと環境構成に注意してください。
これらの方法により、 FFI ::ロードによって報告された未定義のシンボルエラーをすばやく見つけて修正し、C Dynamicライブラリ関数を正常に呼び出すことができます。