1、cd /www/server/php/80/src/ext/ffi
2、phpize
3、./configure CFLAGS="-std=c99" --with-php-config=/www/server/php/80/bin/php-config
4、make
5、make install
开启FFI
在 php.ini 中启用 extension=ffi
在 php.ini 中将 ffi.enable 选项设置为 true
以下是调用实例:
private static $sendchannelcode ='';
public static function attachSign($data) {
$ffiPath = root_path().'vstk'.DIRECTORY_SEPARATOR.'libJITClientAPI64.so'; // 替换为库的实际路径
$ffi =\FFI::cdef(<<<EOF
unsigned char;
typedef void* HANDLE;
typedef unsigned char BYTE;
typedef const char* LPCSTR;
typedef char* LPSTR;
void *memcpy(void *dest, const void *src, size_t n);
long InitServerConnectEx(HANDLE* phContext, LPCSTR pszServerIP, long lServerPort);
long SetConfigFilePath(HANDLE hContext, LPCSTR pszPaths);
long AttachSignEx(HANDLE hContext, LPCSTR pszDN, BYTE* pSrcData, long lSrcLen, LPSTR* ppSignedData, long* plSignedDataLen);
long GetDataEx(HANDLE hContext, BYTE* pData, long* plDataLen);
long GetCertInfoEx(HANDLE hContext, LPCSTR pszType, long lIndex, LPCSTR pszParam, LPSTR pszInfo, long* plInfoLen);
long AttachSignGEx(HANDLE hContext, const char* lpszDN, const char* lpszDigestAlg, const BYTE* pszOrgData, const long nOrgDataLen, BYTE* pszSignDataBuf, long* pSignDataBufLen);
void FinalizeServerConnectEx(HANDLE* phContext);
typedef struct {int array[10];} MyStruct;
EOF,$ffiPath);
$hContext =$ffi->new("HANDLE");
$pszServerIP='117.73.19.167';
$lServerPort = 8003;
$norgDataLen=strlen($data);
$signDatacontent =$ffi->new("BYTE[$norgDataLen]",0);
$ffi->memcpy($signDatacontent,$data,$norgDataLen);//复制内容到内存地址
$pDataBufLen =$ffi->new('long',0);
$pDataBufLenAddr = \FFI::addr($pDataBufLen);
// 初始化服务器连接
$lRet =$ffi->InitServerConnectEx(\FFI::addr($hContext),$pszServerIP,$lServerPort);
if ($lRet != 0) {
echo "InitServerConnectEx error: " . $lRet;
return $lRet;
}
// 设置配置文件路径
$path=root_path().DIRECTORY_SEPARATOR."vstk";
$lRet = $ffi->SetConfigFilePath($hContext, $path);
if ($lRet != 0) {
echo "SetConfigFilePath error: " . $lRet;
$ffi->FinalizeServerConnectEx($hContext);
return $lRet;
}
$lRet= $ffi->AttachSignGEx($hContext,self::$sendchannelcode,"SM3",$signDatacontent,$norgDataLen,NULL,$pDataBufLenAddr);
if($lRet!=0){
echo "AttachSignGEx error:";
return $lRet;
}
// 申请 Base64 签名结果缓存
// 获取结果数据
$dataBuf =$ffi->new("BYTE[$pDataBufLen->cdata]",0);
$lRet = $ffi->GetDataEx($hContext,$dataBuf,$pDataBufLenAddr);
if($lRet!=0){
echo "GetDataEx error:";
return $lRet;
}
$ffi->FinalizeServerConnectEx(\FFI::addr($hContext));
$sign=\FFI::string($dataBuf,$pDataBufLen->cdata);
$base64=base64_encode($sign);
return $base64;
}