C Perl XS中的OpenSSL和线程

C Perl XS中的OpenSSL和线程,c,perl,openssl,pthreads,xs,C,Perl,Openssl,Pthreads,Xs,我正在PerlXS模块中使用OpenSSL。我有一个调用OpenSSL API函数的C函数。出于测试目的,它非常简单(initopenssl、读取密钥、生成RSA对象并使用它、无参数)。无需大检查,地址和内存正常 XS是标准h2xs,在Makefile中带有-lssl和-lcrypto void\u foo(void) { 无符号字符键[3000]; memset(键,0,3000); printf(“\ninit=%d”,SSL_library_init());//init 文件*f=fope

我正在PerlXS模块中使用OpenSSL。我有一个调用OpenSSL API函数的C函数。出于测试目的,它非常简单(initopenssl、读取密钥、生成RSA对象并使用它、无参数)。无需大检查,地址和内存正常

XS是标准h2xs,在
Makefile
中带有
-lssl
-lcrypto

void\u foo(void)
{
无符号字符键[3000];
memset(键,0,3000);
printf(“\ninit=%d”,SSL_library_init());//init
文件*f=fopen(“key.key”,“r”);
printf(“\nf=%d”,f);
int keysize=fread(key,1,3000,f);//readin
printf(“\nn=%d”,按键大小);
fclose(f);
printf(“\nkey=%s”,键);
BIO*BIO=BIO_new_mem_buf(键,键大小);
printf(“\nbio=%ld”,bio);
RSA*pk=(RSA*)PEM_read_bio_RSAPrivateKey(bio,NULL,NULL,NULL);
printf(“\npk=%ld”,pk);
printf(“\nsz=%d”,RSA_size(pk));//****如果在perl线程中,则在此崩溃
printf(“\n\n”);
}
如果我使用纯C/C++的话,这是可行的。如果我将它放在XS模块中,并在线程外的Perl中使用它,也可以。但是如果我把它放在Perl和线程中,它就会崩溃

现在我想说那是因为我没有。但是,如果我查看其他Perl模块(例如,Crypt::OpenSSL::RSA),我也不会在那里找到特殊的线程处理

我对XS很陌生,也许我错过了什么。也许有人能给我一个提示,谢谢

根据以下文件:

在执行任何其他操作之前,必须调用SSL_library_init()。SSL_库_init()不可重入


这意味着您最好在线程启动之前调用一次
SSL\u library\u init
,或者至少确保您具有正确的锁定,并且该函数不会被多次调用,包括可能使用的其他模块不会调用。像这样的模块实际上解决了这个问题。

我找到了答案。我不确定,我不喜欢它,但它似乎是合法的

我的xs中包含很多openssl。但是我没有包括ssl.h

#include <openssl/ssl.h>
#包括
没有编译错误,没有链接器错误。只有在线程中使用时才出现分段错误。即使在线程之外也能工作

如果我包括了h文件,它就可以正常工作了。即使没有添加openssl互斥线程处理

在我试着让我的样品“漂亮”并将其发布到这里后发现。这有点奇怪。。。。我更喜欢编译器错误

但它解释了为什么另一个模块在工作


谢谢你的帮助

什么是“纯C/C++”?“现在我想说,这是因为我没有任何线程处理…”-你可能是对的。“如果我研究了其他Perl模块(例如Crypt::OpenSSL::RSA),我也没有在那里找到特殊的线程处理…”-你不必跟着它们走到悬崖边。请看C::O::RSA。如果这在线程中有效,那么是的,你的也应该如此。它确实会检查
bio
pk
是否为
NULL
,但我猜您确定
bio
pk
都不是
NULL
。我说的地址和指针是可以的。NULL或任何东西都没有问题。我现在确保init只被调用一次,而不是在线程内部。但这并没有什么不同。我希望我不需要OpenSSL线程的互斥锁。因此,我正在与另一个模块进行比较。@chris:根据您目前展示的代码,无法确切说出Perl或其他模块的具体情况以及可能发生的交互。为了获得更好的帮助,请提供一个完全有效的最小示例,使您能够重现您的问题,请参阅。是的,我同意。我在代码中添加了互斥锁,但它仍然不起作用。同样的问题。我将发布一个样本。谢谢“如果我包含h文件,它就可以正常工作。即使没有添加的openssl互斥线程处理…-这真的没有意义。我的代码在线程中不起作用。外面还可以。OpenSSL提供了处理多线程()的函数。我认为问题的原因是我没有使用它们。但在我添加了建议的处理之后,它仍然不起作用。希望现在一切都清楚了。您在问题中写道:“如果我使用纯C/C++,那就行了。”在您的“纯C/C++”测试中,它在不包括h文件的情况下有效吗?使用纯C组件XS。它是用C语言编写的,如果我试过C代码,它就可以工作了。我没有在C中用线程尝试它。但是,作为带有perl线程的XS。
#include <openssl/ssl.h>