编译 c 和 c++ 模块

Posted

技术标签:

【中文标题】编译 c 和 c++ 模块【英文标题】:Compiling c and c++ module 【发布时间】:2020-06-14 00:21:14 【问题描述】:

假设我正在开发一个已经存在的 freeswitch 模块 (https://github.com/signalwire/freeswitch)。这些是动态加载的。

我过去创建过模块,这不是我的问题。我的问题来自一个已经存在的模块,我们称之为 my_module。在这个模块中,我添加了一个新功能,我需要解密以 AES 加密的 jwt 令牌参数。

现有的模块主文件,主freeSWITCH加载器加载的文件是C.,我们这样说:

#include <switch.h>
#include <switch_json.h>
#include <switch_stun.h>
#include <jwt.h>

#include "token_crypto.h" <-- This is my addition

...
<some stuff goes here>

有时我会这样做:

 plaintext_len = token_decrypt( *token_encoded, plaintext );

我的 token_crypto.h 是

SWITCH_BEGIN_EXTERN_C

#include <stdio.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/sha.h>


void handleErrors(unsigned char *ciphertext);
int gcm_decrypt(unsigned char *ciphertext, int ciphertext_len,
            unsigned char *aad, int aad_len,
            unsigned char *tag,
            unsigned char *key,
            unsigned char *iv, int iv_len,
            unsigned char *plaintext);
int token_decrypt( const char token_encoded, unsigned char *plaintext );


SWITCH_END_EXTERN_C

然后是token_crypto.cpp中的实际实现

我在 Makefile.am 中添加了编译 token_crypto 的要求,如下所示:

mod_mymodule_la_SOURCES  = \
    base64url.cpp \
    token_crypto.cpp \
    mod_mymodule.c

然后代码编译正常,但是当我尝试加载它时,我得到:

**/usr/local/freeswitch/mod/mod_mymodule.so: undefined symbol: token_decrypt**

我知道链接器找不到已编译的引用,但我就是不知道如何将它们全部链接起来......

可以在此处找到示例 Makefile https://github.com/signalwire/freeswitch/blob/master/src/mod/applications/mod_skel/Makefile.am

也许我应该指出,该 .c 文件上还有其他 cpp 源代码正在使用中。

我知道,通过使用“extern c”,编译器不会破坏函数名……但就实际使用 c 源文件中的函数而言,这意味着什么?

诸如“google this”、“google that”之类的 cmets 没有帮助。显然,我在来这里之前已经做了所有这些,所以......

【问题讨论】:

您的“C”源文件 token_crypto.cpp 具有 cpp 扩展名,因此链接器使用重命名的名称 google ' extern "C"' 【参考方案1】:

所以,显然“extern c”包含头文件是不够的。出于某种原因,这就是我所记得的。

如果没有“extern c”也不是实际的 cpp 实现,那么函数将被破坏。将“extern C”添加到实现中对我有用。

还是谢谢大家。

【讨论】:

以上是关于编译 c 和 c++ 模块的主要内容,如果未能解决你的问题,请参考以下文章

C程序如何调用C++接口?

c++面试常见300问

使用不同的C++支持库的模块混合开发时,引发异常展开不正常,抛异常竟引出一个SIGSEGV

编译动态内存模块时 Icarus Verilog 崩溃

模块详解

C++20 模块“循环依赖”