cppTest-3.0:指针相关-3(指针与函数)

本文介绍了C++中指针与函数的关系,演示了如何使用指针调用函数及将函数作为参数传递的方法。通过具体实例,展示了如何定义和使用函数指针,包括对数组求和的操作以及无参无返回值的函数调用。
/**
 *cppTest-3.0:指针相关-3(指针与函数)
 *
 *author 炜sama
 */
#include<iostream.h>
int SumArray(int arr[],int n);
void fun();
void main()
{
	static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
	int *p,total1,total2;
	int (*pt)(int *,int); // pt与SumArray形式应保持一致
	pt=SumArray;//赋值到函数指针时不能带参数!
	p=a[0];
	total1=SumArray(p,12);
	total2=(*pt)(p,12);//成功,教程上推荐的方法
	//total2=*pt(p,12);//编译错误,错误的调用方法
	//total2=pt(p,12);//成功
	cout<<"total1="<<total1<<", total2="<<total2<<endl;
	
	void (*pFun)();
	pFun=fun;

	//*pFun();//编译错误,错误的调用方法
	//pFun;//没反应,错误的调用方法
	pFun();//成功
	//(*pFun);//没反应,错误的调用方法
	(*pFun)();//成功,教程上推荐的方法
}
int SumArray(int arr[],int n)
{
	int i,sum=0;
	for(i=0;i<n;i++) sum=sum+arr[i];
		return sum;
}
void fun(){
	cout<<"无参无返回值fun"<<endl;
}

<think>好的,用户现在遇到了一个编译错误,错误信息是“expression must be an lvalue or a function designator”,出现在尝试将`_env`赋值为`&1`的地方。用户需要给`env`赋一个确定的有效值,而不是无效的指针。 首先,我需要理解用户的问题。用户之前可能尝试过错误的赋值方式,比如`&1`,这显然是不正确的,因为`1`是一个字面量,不是一个变量,无法取地址。用户需要的是为`JNIEnv*`类型的`_env`变量赋予一个有效的、非空的指针,确保测试用例能正确运行。 接下来,我需要考虑如何正确构造一个有效的`JNIEnv`对象。根据之前的对话,用户可能没有测试框架提供的`CppTest_CreateMockJNIEnv`函数,所以需要手动构造。`JNIEnv`结构体在JNI规范中通常定义为包含一个指向`JNINativeInterface`结构体的指针,该结构体包含各种JNI函数指针。 因此,正确的步骤应该是: 1. 定义一个`JNINativeInterface`类型的结构体实例,其中包含桩函数指针,这些桩函数模拟实际的JNI函数行为。 2. 定义一个`JNIEnv`类型的结构体实例,其`functions`成员指向上述的`JNINativeInterface`实例。 3. 将`_env`指针指向这个`JNIEnv`实例,确保其非空。 需要注意的是,`JNINativeInterface`中的函数指针需要JNI规范中的函数签名一致,否则可能导致调用时出现错误。此外,用户需要确保这些桩函数的实现符合测试需求,比如返回特定的值来模拟成功或失败的情况。 另外,用户之前的错误赋值`&1`是因为可能误解了如何构造有效指针,需要明确指出必须使用一个实际的变量地址,而不是字面量的地址。 最后,需要提供具体的代码示例,帮助用户正确赋值`_env`,并解释每一步的作用,确保用户理解为什么这样做是正确的,避免再次出现类似错误。 </think>该错误是由于尝试将 `_env` 赋值为无效的指针(`&1`)导致的。`1` 是字面量(右值),无法取地址(`&` 操作符要求操作数是左值,即内存中可寻址的变量)。需通过**手动构造有效 `JNIEnv` 对象**为 `_env` 赋确定值。以下是具体方案: ### 1. 错误原因分析 `::JNIEnv* _env = &1;` 试图取字面量 `1` 的地址,但字面量存储在只读内存中且无固定地址,`&` 操作符无法作用于非左值(如字面量、临时值),因此编译器报错“expression must be an lvalue”(表达式必须是左值)。 ### 2. 正确赋值的核心逻辑 `_env` 需指向一个**实际存在的 `JNIEnv` 结构体变量**(左值),且该结构体的 `functions` 成员需指向有效的 `JNINativeInterface` 结构体(包含桩函数指针)。步骤如下: ### 3. 具体实现步骤(附代码示例) #### (1)定义 `JNINativeInterface` 结构体并绑定桩函数 `JNINativeInterface` 是 JNI 规范中定义的结构体,包含所有 JNI 函数指针(如 `FindClass`、`GetJavaVM`)。需手动初始化该结构体,并将函数指针指向自定义的桩函数: ```cpp // 定义桩函数 JNI 函数签名一致) static jclass Stub_FindClass(JNIEnv* env, const char* className) { // 模拟查找类失败(返回 NULL) return NULL; } static jint Stub_GetJavaVM(JNIEnv* env, JavaVM** vm) { *vm = NULL; // 假设不需要实际 JavaVM 对象 return JNI_OK; // 模拟成功 } // 初始化 JNINativeInterface 结构体,绑定桩函数 struct JNINativeInterface g_mockJNIInterface = { // 其他 JNI 函数指针(若被测代码未使用,可设为 NULL 或默认实现) .GetJavaVM = Stub_GetJavaVM, // 绑定 GetJavaVM 桩函数 .FindClass = Stub_FindClass, // 绑定 FindClass 桩函数 // ... 按需补充其他 JNI 函数指针(如 NewStringUTF、GetMethodID 等) }; ``` #### (2)定义 `JNIEnv` 结构体并关联 `JNINativeInterface` `JNIEnv` 结构体在 JNI 规范中通常定义为 `struct JNIEnv_ { const struct JNINativeInterface* functions; };`。需创建一个 `JNIEnv_` 实例,使其 `functions` 成员指向步骤(1)中的 `g_mockJNIInterface`: ```cpp // 定义 JNIEnv 实例,指向模拟的 JNINativeInterface struct JNIEnv_ g_mockJNIEnv = { &g_mockJNIInterface }; ``` #### (3)为 `_env` 赋确定值(指向 `g_mockJNIEnv`) 将 `_env` 指针指向步骤(2)中定义的 `g_mockJNIEnv` 变量(左值),确保其有效且非空: ```cpp ::JNIEnv* _env = &g_mockJNIEnv; // 正确赋值:取左值的地址 ``` #### (4)完整测试用例代码(修正后) ```cpp // 步骤1:定义桩函数 JNI 函数签名一致) static jclass Stub_FindClass(JNIEnv* env, const char* className) { return NULL; // 模拟 FindClass 失败 } static jint Stub_GetJavaVM(JNIEnv* env, JavaVM** vm) { *vm = NULL; return JNI_OK; // 模拟 GetJavaVM 成功 } // 步骤2:初始化 JNINativeInterface 结构体,绑定桩函数 struct JNINativeInterface g_mockJNIInterface = { .GetJavaVM = Stub_GetJavaVM, .FindClass = Stub_FindClass, // 其他 JNI 函数指针(按需补充,未使用的可设为 NULL) }; // 步骤3:定义 JNIEnv 实例,关联 JNINativeInterface struct JNIEnv_ g_mockJNIEnv = { &g_mockJNIInterface }; void TestSuite_update2dsdk_cpp_802ca10e::test_Java_com_isa_navi_jni_hmi_HmiProxyJNI_InitializeCpp_0() { // 步骤4:为 env 赋确定值(指向有效 JNIEnv 实例) ::JNIEnv* _env = &g_mockJNIEnv; // 正确赋值:取左值的地址 // 验证 env 非空(使用框架支持的断言) CPPTEST_ASSERT(_env != NULL); /* Initializing argument 2 (thiz) */ ::jobject _thiz = 0; // 注册桩函数回调(若框架需要) CPPTEST_REGISTER_STUB_CALLBACK("JNIEnv_::GetJavaVM", &Stub_GetJavaVM); CPPTEST_REGISTER_STUB_CALLBACK("JNIEnv_::FindClass", &Stub_FindClass); /* Tested function call */ ::Java_com_isa_navi_jni_hmi_HmiProxyJNI_InitializeCpp(_env, _thiz); /* Post-condition check */ CPPTEST_POST_CONDITION_PTR("JNIEnv * _env ", (_env)); CPPTEST_POST_CONDITION_PTR("::jobject _thiz", (_thiz)); } ``` ### 4. 关键注意事项 - **左值要求**:`_env` 必须指向一个实际存在的变量(如 `g_mockJNIEnv`),不能是字面量或临时值的地址。 - **桩函数完整性**:若被测代码调用了 `JNINativeInterface` 中未绑定的 JNI 函数(如 `GetMethodID`),需补充对应的桩函数,否则可能导致崩溃。 - **符号一致性**:若测试框架(如 CppTest)通过函数名匹配桩函数(如 `CPPTEST_REGISTER_STUB_CALLBACK`),需确保桩函数的符号名框架预期一致(可能需要 `extern "C"` 避免 C++ 名称修饰)。 ### 结论 通过手动构造 `JNIEnv` 实例并绑定桩函数,为 `_env` 赋有效左值的地址,可解决编译错误并确保测试用例正确执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值