Error处理:Invalid arguments ' Candidates are: void * memcpy(void *, const void *, ?)

本文介绍JNI开发过程中因size_t参数引起的错误“Invalid arguments”,并提供两种解决方案:一是使用new、strcpy等替代malloc、memcpy;二是通过配置让系统识别size_t类型。

Error处理:Invalid arguments ' Candidates are: void * memcpy(void *, const void *, ?)




JNI开发的过程中遇到的问题。

现象如下:

Invalid arguments ' Candidates are: void * memcpy(void *, const void *, ?)
Invalid arguments 'Candidates are: void * malloc(?)

在包含的头文件中也看到函数的原型,如下:

extern __mallocfunc void*  malloc(size_t);
extern void*  memcpy(void *, const void *, size_t);

错误提示中:Invalid arguments,意味着参数无效,很明显是size_t这个参数不被正常识别造成的。


源于此分析,那么凡是使用size_t类型参数的方法均会出现这个问题,例如:memset,memccpy,memchr,memcmp等。


鉴于此,要解决这个问题,思路有二,第一:使用其他方法进行替代,不使用memcpy,malloc,memset方法。第二:让系统能够正常识别size_t类型,此为根本解决此问题之道。下面就两种思路各提供详细解决方案。


第一:替代法


可以使用new、strcpy来替代malloc、memcpy;这里针对malloc,memcpy两个方法,其他方法可以自己找相应的方法来替代。

例如:

原来为:

 const char* tmp = env->GetStringUTFChars(jstr_mac,NULL);
 
size_t len= strlen(tmp)+ 1;

 char*mac = (char*) malloc(len);
 
memcpy(mac, tmp, len);

 

可以改为:

 const char* tmp = env->GetStringUTFChars(jstr_mac,NULL);
 
int len= strlen(tmp)+ 1;
 
char*mac = new char[len];
 
strcpy(mac, tmp);


第二:让系统能够识别size_t类型

方案如下:

  1. 右击项目工程properties -> C/C++ General -> Paths and Symbols。

  2. 选择 "Includes" 标签

F:\android-ndk-r9b\platforms\android-19\arch-arm\usr\include

F:\android-ndk-r9b\toolchains\arm-linux-androideabi-4.8\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.8\include

如此,该问题可解。


备注说明:

还可在将以下两个头文件库添加到项目的include中:

F:\android-ndk-r9b\sources\cxx-stl\gnu-libstdc++\4.8\include

F:\android-ndk-r9b\sources\cxx-stl\gnu-libstdc++\4.8\libs\armeabi-v7a\include


----------------------------------

欢迎浏览、技术交流
请尊重劳动成果
转载请注明出处,谢谢!

http://blog.youkuaiyun.com/netwalk/article/details/22295585



在C/C++编译过程中,出现错误 `error: invalid conversion from ‘void* (*)()’ to ‘void* (*)(void*)’` 是由于函数指针类型的不匹配导致的。具体来说,该错误表示尝试将一个没有参数列表的函数指针(即 `void* (*)()`)赋值给一个期望接受 `void*` 参数的函数指针(即 `void* (*)(void*)`),这种隐式转换在C++中是不允许的。 此类问题常见于使用 POSIX 线程库(`pthread`)时传递线程函数的情况。`pthread_create` 函数期望的线程函数原型为 `void* (*start_routine)(void*)`,而如果定义的线程函数形式为 `void* thread_function()` 或者没有正确声明参数类型,则会导致此编译错误[^3]。 ### 解决方法 1. **修改函数定义** 确保线程函数接受一个 `void*` 类型的参数,并返回 `void*` 类型。例如: ```cpp void* thread_function(void* arg) { // 线程执行内容 return nullptr; } ``` 2. **正确使用函数指针类型** 如果需要将其他类型的函数适配为符合 `pthread_create` 要求的形式,可以通过中间函数进行封装。例如: ```cpp extern "C" void* thread_wrapper(void* arg) { return reinterpret_cast<void*>(thread_function()); } ``` 在调用 `pthread_create` 时使用 `thread_wrapper` 作为线程入口函数。 3. **避免C与C++混用时的类型不匹配** 在C++中调用C语言风格的函数时,应确保函数指针类型一致,必要时使用 `extern "C"` 来防止名称修饰问题,并显式地进行类型转换(如 `reinterpret_cast`)以确保兼容性[^3]。 4. **使用C++11及以上标准的线程库替代方案** 如果项目允许使用现代C++标准,建议改用 `<thread>` 库来创建线程,它提供了更安全、更灵活的接口,并且可以自动处理函数对象和参数绑定的问题: ```cpp #include <thread> void thread_function() { // 线程执行内容 } int main() { std::thread t(thread_function); t.join(); return 0; } ``` 通过上述方式可以有效解决 `invalid conversion from ‘void* (*)()’ to ‘void* (*)(void*)’` 的编译错误,并提升代码的可维护性和可移植性。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JerryHe

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值