欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C项目如何转C++项目——error LNK2019: 无法解析的外部符号 "unsigned int __cdecl

程序员文章站 2024-01-28 09:35:52
...

实验的时候,需要调用的库是C++版本,而进行操作的源项目是C版本,这个时候就需要将C版本的项目转化为C++。
C语言项目转化为C++项目还是比较简单的。

步骤:

  1. 把需要修改的.c 文件直接改成 .cpp。
  2. 针对.cpp的报错进行一一修改,基本是内存分配是类型转化问题,解决方法:强制类型装换; 还有一类是函数符号无法解析。解决方案及举例如下:

错误 79 error LNK2019: 无法解析的外部符号 “unsigned int __cdecl
FLAC__replaygain_synthesis__apply_gain(unsigned char *,int,int,int
const * const * const,unsigned int,unsigned int,unsigned int,unsigned
int,double,int,int,struct DitherContext

分析:这个问题原因是CPP文件调用了C文件里面的函数,而C文件编译时对函数的处理与CPP不同。

  1. C编译器的函数名修饰规则
    对于__stdcall调用约定,编译器和链接器会在输出函数名前加上一个下划线前缀,函数名后面加上一个“@”符号和其参数的字节数,例如[email protected]__cdecl调用约定仅在输出函数名前加上一个下划线前缀,例如_functionname.
  2. C++编译器的函数名修饰规则
    C++的函数名修饰规则有些复杂,但是信息更充分,通过分析修饰名不仅能够知道函数的调用方式,返回值类型,参数个数甚至参数类型。不管__cdecl,__fastcall还是__stdcall调用方式,函数修饰都是以一个“?”开始,后面紧跟函数的名字,再后面是参数表的开始标识和按照参数类型代号拼出的参数表。对于__stdcall方式,参数表的开始标识是“@@YG”,对于__cdecl方式则是“@@YA”

所以问题就变成了:C++如何调用C函数?
解决方法:

a. 编写一个C++风格的头文件,在这里添加extern修饰符。在不修改源C文件的情况下,最优的处理。

// CStack.h  
extern "C" {  
#include "Stack.h";  
}  

b. 在C头文件中加上extern修饰符。

extern "C" {  
void DeleteStack(Stack stack);  
void PrintStack(Stack stack);  
void Pop(Stack stack);  
}  

reference:
C++调用C函数

以上。
总结来讲,C转C++项目,基本没有难度,分析清楚具体原因,具体应对即可,能尽量使用.c 源文件,就直接cpp调用c,这样子的改动量最小。