getenv的一个坑

本文探讨了C#调用C++DLL时,由于getenv和setenv函数特性导致的环境变量更新不同步问题。getenv读取的是加载时初始化的全局数组,而setenv同时修改全局数组和进程环境变量。C#和Windows API直接操作进程环境变量,可能造成C++代码中环境变量值未更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

getenv和setenv这一对,是stdlib中提供的获取和设置当前进程环境变量的函数,我本人也常常使用。

今天写一个小程序,从C#要调用C++的DLL,而C++的代码依赖某一环境变量“MAK_VRLDIR”,相关代码如下:

...
const char* vrlDir=getenv("MAK_VRLDIR");
...

刚开始,我并没有当回事,直接在C#代码中写了如下代码:

System.Environment.SetEnvironmentVariable("MAK_VRLDIR", "C:\\VRL", System.EnvironmentVariableTarget.Process);

随即调试,发现C++的DLL总是不能正常工作。

先说结论,再说调试过程:

getenv函数读取的环境变量的值,保存在一个全局数组里,该数组在DLL加载时,自动从进程环境变量读取初始化,随后的getenv,都是从该全局数组内读取(后面会验证)。

setenv函数,既修改这个全局数组,也修改进程的环境变量。

Windows提供的Get\SetEnvironmentVariable和c#的Get\SetEnvironmentVariable都是直接操作进程环境变量。

存在的问题是:

如系统中有环境变量MAK_VRLDIR=C:\VRL,默认情况下调用getenv和GetEnvironmentVariable都没有问题。

但是如果我调用SetEnvironmentVariable(MAK_VRLDIR=C:\TEST),这时候进程的环境变量已经更改,但是getenv("MAK_VRLDIR")得到的结果还是旧的C:\VRL。

 

调试过程后面有时间补上,查看进程的环境变量,可以使用Procexp等软件。

 

 

 

 

<think>我们正在讨论的是UniApp小程序中,通过WebView嵌入H5页面,然后从H5页面返回到小程序的上一个页面的问题。 根据引用[4]中的示例,在H5页面中可以通过监听`UniAppJSBridgeReady`事件,然后调用`uni.navigateBack()`方法来实现返回。 此外,引用[2]中提到,从H5返回到小程序时需要注意一些,所以我们需要确保H5页面中正确引入了UniApp的SDK,并且事件监听正确。具体步骤: 1.在H5页面中,确保引入了UniApp的JSSDK(通常是在H5页面的HTML中引入一个uni.webview.js文件)。 2.在H5页面中,编写JavaScript代码,监听`UniAppJSBridgeReady`事件,该事件表示桥接准备就绪,可以调用UniApp的方法了。 3.在事件回调中,为某个按钮(例如返回按钮)添加点击事件,在点击事件中调用`uni.navigateBack()`方法。注意:如果H5页面中没有引入SDK,或者没有正确监听事件,则无法调用`uni.navigateBack()`。 另外,引用[3]中提到了另一种方法:通过改变H5页面的URL(带参数)来触发WebView的load事件,然后在WebView页面监听URL变化,根据参数执行小程序的导航操作。但这种方法会导致页面刷新,且需要业务域名,相对复杂。因此,我们优先使用第一种方法。所以,总结实现步骤:1.在H5页面中引入uni-app的SDK(通常由uni-app官方提供,例如:https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js) 2.在H5页面中编写代码,在`UniAppJSBridgeReady`事件触发后,为返回按钮绑定事件,调用`uni.navigateBack()` 示例H5页面代码片段: ```html<!DOCTYPEhtml><html><head><meta charset="utf-8"><title>H5页面</title><!--引入uni-app的SDK--><scriptsrc="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script></head> <body><h1>这是H5页面</h1><button class="back-btn">返回小程序</button><script>//等待UniAppJSBridge准备就绪document.addEventListener('UniAppJSBridgeReady',function(){//获取按钮元素var backButton= document.querySelector('.back-btn');//添加点击事件backButton.addEventListener('click', function() {//调用uni.navigateBack()返回上一页uni.navigateBack();});});</script></body> </html>``` 在小程序端,使用web-view组件加载这个H5页面:```html<template><web-viewsrc="https://你的域名/上面的H5页面.html"></web-view> </template>``` 注意事项: -H5页面必须部署在配置的业务域名下,否则无法加载(微信小程序要求)。 -确保H5页面中引入的SDK地址正确且可访问。-如果H5页面中有多个返回按钮,需要为每个按钮都绑定事件,或者使用事件委托。如果按照以上步骤操作,应该可以实现从H5页面点击按钮返回小程序的上一个页面。如果遇到问题,请检查: 1.是否引入了正确的SDK。2.是否监听了`UniAppJSBridgeReady`事件。 3.按钮点击事件绑定是否正确。4.业务域名是否配置。另外,引用[2]中提到,从H5返回小程序时,如果使用uni.navigateBack()不起作用,可能是因为H5页面中SDK引入路径不对,或者事件监听没有生效。因此,请仔细检查这些点。 如果以上方法仍然不行,可以考虑使用第二种方法(通过URL参数变化触发),但这种方法相对复杂,且需要刷新页面,所以作为备选方案。第二种方法示例(不推荐,仅作备选):在H5页面中,通过改变URL(添加参数)来触发web-view的@load事件,然后在web-view的页面中监听URL变化,解析参数,如果参数中有返回指令,则执行小程序的返回操作。在小程序页面中:```html<template><web-view:src="url" @load="onLoad"></web-view></template> <script> exportdefault {data() {return{url:'https://你的H5页面地址'}},methods: {onLoad(e) {//解析URL,如果URL中有返回参数,则执行返回//例如,H5页面在需要返回时,会在URL后面加上?action=back//这里需要解析e.detail.url,判断是否有action=backconsturl =e.detail.url;if(url.includes('action=back')){uni.navigateBack();}}} }</script> ```在H5页面中,需要返回时:```javascript//改变URL,添加action=back参数window.location.href= window.location.href.split('?')[0] +'?action=back';``` 这种方法会刷新页面,所以体验不好,而且需要小程序端和H5端约定好参数规则。 因此,优先推荐第一种方法。相关问题:1.在UniApp中,如何从WebView加载的H5页面跳转到小程序的指定页面(不仅仅是返回上一页)? 2. UniApp的WebView组件与H5页面通信还有哪些方法? 3.在微信小程序中,如何配置WebView的业务域名?</think>在UniApp小程序中,通过WebView嵌入的H5页面返回到小程序上一页,可通过以下两种方法实现: ### 方法1:H5页面调用UniApp导航API(推荐) **步骤:** 1. **H5页面引入UniApp SDK** 在H5页面头部添加官方SDK(确保使用最新版本): ```html <script src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.4.js"></script> ``` 2. **H5页面添加返回逻辑** 监听`UniAppJSBridgeReady`事件后调用`uni.navigateBack()`: ```html <button onclick="backToMiniProgram()">返回小程序</button> <script> function backToMiniProgram() { document.addEventListener('UniAppJSBridgeReady', function() { uni.navigateBack({ delta: 1 }); // 返回上一页 }); } </script> ``` ### 方法2:URL参数触发WebView监听(兼容方案) **步骤:** 1. **小程序端监听WebView URL变化** ```html <web-view :src="h5Url" @load="onWebviewLoad"></web-view> ``` ```javascript methods: { onWebviewLoad(e) { const url = e.detail.url; if (url.includes('action=back')) { // 检测H5触发的返回指令 uni.navigateBack({ delta: 1 }); } } } ``` 2. **H5页面触发返回** ```javascript // H5页面中点击按钮时执行 function triggerBack() { const newUrl = window.location.href + (window.location.href.includes('?') ? '&' : '?') + 'action=back'; window.location.href = newUrl; // 改变URL触发WebView的@load事件 } ``` ### 关键注意事项 1. **域名白名单** - 必须在小程序后台配置H5域名的业务域名(微信小程序要求) - 本地调试时开启「不校验合法域名」 2. **SDK兼容性** - 使用`uni.getEnv()`判断环境(微信/支付宝等) - 部分平台需添加超时容错: ```javascript setTimeout(() => { if (window.uni) uni.navigateBack(); else alert("SDK加载失败"); }, 500); ``` 3. **iOS额外配置** 在`manifest.json`添加: ```json "app-plus": { "webview": { "userAgent": "uni-app" } } ``` > **实际案例参考**:某电商H5页面通过`uni.postMessage`发送返回指令,小程序通过`@message`监听实现无刷新返回[^3]。若遇H5刷新问题,建议采用WebSocket双向通信替代URL参数方案。 --- ### 相关问题 1. **如何实现H5页面跳转到小程序指定页面(非返回)?** > 使用`uni.navigateTo({ url: '/pages/target' })`,需提前在小程序全局路由注册页面 2. **WebView与H5实时通信有哪些高效方案?** > 优先推荐WebSocket(支持双向通信),次选`uni.postMessage`+`@message`事件监听[^3] 3. **为什么uni.navigateBack()在部分安卓机失效?** > 通常因WebView缓存机制导致,需在H5页面强制初始化SDK:`window.uni = window.uni || {};` 4. **未配置业务域名时如何调试?** > 微信开发者工具中开启「不校验域名」选项,真机调试需使用测试版小程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值