C++如何调用C函数?

时间:2022-09-22 09:15:50
我新建了个MFC工程,包含了MD5的C文件,并且按照__cdecl编译成C代码,但是我在工程主对话框的.cpp文件调用时总出现如下错误,用C的时候是没有的:
error C2660: “MD5Init”: 函数不接受 1 个参数
error C2660: “MD5Update”: 函数不接受 3 个参数
error C2660: “MD5Final”: 函数不接受 2 个参数


extern "C"{
#include "md5.h"
};
...
MD5Init( &context );
MD5Update( &context, szInput, nInLen );
MD5Final( szOutput, &context );

12 个解决方案

#1


解决了,算你们狠。
/*1.把函数声明改成(md5.h中的)*/
void MD5Init   (MD5_CTX *);
void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
void MD5Final  (unsigned char [16], MD5_CTX *);

/*2.在md5c.c右键 ---> 属性 ---> C/C++ ---> 高级 ---> 
调用约定:与工程相同(我这里是__stdcall(/GZ)),编译为:C代码。
如果调用约定与工程的不相同,只能用汇编调用了。
还有预编译头,我这里为:不使用预编译头*/

/*3.包含头文件时用extern "C"*/
extern "C"{
#include "md5.h"
};

//4.这样就可以使用了:
MD5Init(&context);
MD5Update(&context, (unsigned char *)szName, dtLength);
MD5Final(szHash, &context);

#2


来个人,送分。

#3


额。。。解决办法很详尽·

#4


看到你的解决方法之前,还以为是你参数传的不对~

#5


恭喜楼主解决问题

#6


我转载,以后可能用得到。

#7


我也以为他传的参数不对呢。

#8


我在想一个问题,
楼主如果已经有MD5的C代码,可以直接使用C++编译
去掉那些extern c
这样不可行吗?

#9


你原来怎么写的,并没有贴出来,别人也不好解决。如果有代码,也就无所谓c、c++了。

#10


引用 8 楼  的回复:
我在想一个问题,
楼主如果已经有MD5的C代码,可以直接使用C++编译
去掉那些extern c
这样不可行吗?

如果不加extern "C"那么编译器就会按C++函数名调用。
C函数名:_FunctionName
C++函数名:?functionname@@YG****@Z
这样链接器就找不到该函数了。进而报错:
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Final(unsigned char * const,struct MD5_CTX *)" (?MD5Final@@YGXQAEPAUMD5_CTX@@@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Update(struct MD5_CTX *,unsigned char *,unsigned int)" (?MD5Update@@YGXPAUMD5_CTX@@PAEI@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Init(struct MD5_CTX *)" (?MD5Init@@YGXPAUMD5_CTX@@@Z)

#11


引用 9 楼  的回复:
你原来怎么写的,并没有贴出来,别人也不好解决。如果有代码,也就无所谓c、c++了。

原来只有第4步:

    MD5Init(&context);
    MD5Update(&context, (unsigned char *)szName, dtLength);
    MD5Final(szHash, &context);

#12


引用 10 楼 WhyThatMe 的回复:
[Quote=引用 8 楼  的回复:]

我在想一个问题,
楼主如果已经有MD5的C代码,可以直接使用C++编译
去掉那些extern c
这样不可行吗?

如果不加extern "C"那么编译器就会按C++函数名调用。
C函数名:_FunctionName
C++函数名:?functionname@@YG****@Z
这样链接器就找不到该函数了。进而报错:
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Final(unsigned char * const,struct MD5_CTX *)" (?MD5Final@@YGXQAEPAUMD5_CTX@@@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Update(struct MD5_CTX *,unsigned char *,unsigned int)" (?MD5Update@@YGXPAUMD5_CTX@@PAEI@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Init(struct MD5_CTX *)" (?MD5Init@@YGXPAUMD5_CTX@@@Z)

C函数名那个是gcc干的吧?C++会怎么做?

$gcc -c msg.c
$nm msg.o
                 U __errno_location
                 U __stack_chk_fail
0000000000000423 T clear_queue
                 U ftok
0000000000000000 T get_msgid_by_file
                 U memcmp
                 U memcpy
00000000000002bc T msg_rcv
00000000000005f2 T msg_rcv_nowait
00000000000004db T msg_snd
0000000000000746 T msg_snd_nowait
                 U msgctl
                 U msgget
                 U msgrcv
                 U msgsnd
                 U printf
000000000000085d T remove_queue
                 U strerror
$g++ -c msg.c
$nm msg.o
0000000000000421 T _Z11clear_queuel
0000000000000870 T _Z12remove_queuel
0000000000000605 T _Z14msg_rcv_nowaitlPcPi
0000000000000754 T _Z14msg_snd_nowaitlPci
0000000000000000 T _Z17get_msgid_by_filePccc
00000000000002bf T _Z7msg_rcvlPcPi
00000000000004e9 T _Z7msg_sndlPci
                 U __errno_location
                 U __stack_chk_fail
                 U ftok
                 U memcmp
                 U memcpy
                 U msgctl
                 U msgget
                 U msgrcv
                 U msgsnd
                 U printf
                 U strerror

#1


解决了,算你们狠。
/*1.把函数声明改成(md5.h中的)*/
void MD5Init   (MD5_CTX *);
void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
void MD5Final  (unsigned char [16], MD5_CTX *);

/*2.在md5c.c右键 ---> 属性 ---> C/C++ ---> 高级 ---> 
调用约定:与工程相同(我这里是__stdcall(/GZ)),编译为:C代码。
如果调用约定与工程的不相同,只能用汇编调用了。
还有预编译头,我这里为:不使用预编译头*/

/*3.包含头文件时用extern "C"*/
extern "C"{
#include "md5.h"
};

//4.这样就可以使用了:
MD5Init(&context);
MD5Update(&context, (unsigned char *)szName, dtLength);
MD5Final(szHash, &context);

#2


来个人,送分。

#3


额。。。解决办法很详尽·

#4


看到你的解决方法之前,还以为是你参数传的不对~

#5


恭喜楼主解决问题

#6


我转载,以后可能用得到。

#7


我也以为他传的参数不对呢。

#8


我在想一个问题,
楼主如果已经有MD5的C代码,可以直接使用C++编译
去掉那些extern c
这样不可行吗?

#9


你原来怎么写的,并没有贴出来,别人也不好解决。如果有代码,也就无所谓c、c++了。

#10


引用 8 楼  的回复:
我在想一个问题,
楼主如果已经有MD5的C代码,可以直接使用C++编译
去掉那些extern c
这样不可行吗?

如果不加extern "C"那么编译器就会按C++函数名调用。
C函数名:_FunctionName
C++函数名:?functionname@@YG****@Z
这样链接器就找不到该函数了。进而报错:
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Final(unsigned char * const,struct MD5_CTX *)" (?MD5Final@@YGXQAEPAUMD5_CTX@@@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Update(struct MD5_CTX *,unsigned char *,unsigned int)" (?MD5Update@@YGXPAUMD5_CTX@@PAEI@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Init(struct MD5_CTX *)" (?MD5Init@@YGXPAUMD5_CTX@@@Z)

#11


引用 9 楼  的回复:
你原来怎么写的,并没有贴出来,别人也不好解决。如果有代码,也就无所谓c、c++了。

原来只有第4步:

    MD5Init(&context);
    MD5Update(&context, (unsigned char *)szName, dtLength);
    MD5Final(szHash, &context);

#12


引用 10 楼 WhyThatMe 的回复:
[Quote=引用 8 楼  的回复:]

我在想一个问题,
楼主如果已经有MD5的C代码,可以直接使用C++编译
去掉那些extern c
这样不可行吗?

如果不加extern "C"那么编译器就会按C++函数名调用。
C函数名:_FunctionName
C++函数名:?functionname@@YG****@Z
这样链接器就找不到该函数了。进而报错:
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Final(unsigned char * const,struct MD5_CTX *)" (?MD5Final@@YGXQAEPAUMD5_CTX@@@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Update(struct MD5_CTX *,unsigned char *,unsigned int)" (?MD5Update@@YGXPAUMD5_CTX@@PAEI@Z)
1>CryptDlg.obj : error LNK2001: 无法解析的外部符号 "void __stdcall MD5Init(struct MD5_CTX *)" (?MD5Init@@YGXPAUMD5_CTX@@@Z)

C函数名那个是gcc干的吧?C++会怎么做?

$gcc -c msg.c
$nm msg.o
                 U __errno_location
                 U __stack_chk_fail
0000000000000423 T clear_queue
                 U ftok
0000000000000000 T get_msgid_by_file
                 U memcmp
                 U memcpy
00000000000002bc T msg_rcv
00000000000005f2 T msg_rcv_nowait
00000000000004db T msg_snd
0000000000000746 T msg_snd_nowait
                 U msgctl
                 U msgget
                 U msgrcv
                 U msgsnd
                 U printf
000000000000085d T remove_queue
                 U strerror
$g++ -c msg.c
$nm msg.o
0000000000000421 T _Z11clear_queuel
0000000000000870 T _Z12remove_queuel
0000000000000605 T _Z14msg_rcv_nowaitlPcPi
0000000000000754 T _Z14msg_snd_nowaitlPci
0000000000000000 T _Z17get_msgid_by_filePccc
00000000000002bf T _Z7msg_rcvlPcPi
00000000000004e9 T _Z7msg_sndlPci
                 U __errno_location
                 U __stack_chk_fail
                 U ftok
                 U memcmp
                 U memcpy
                 U msgctl
                 U msgget
                 U msgrcv
                 U msgsnd
                 U printf
                 U strerror