Dynamic Linking Error: Win32 Error 126问题排查

47 篇文章 7 订阅
43 篇文章 19 订阅

    如题所示,这个问题是我在electron项目中使用ffi调用动态链接库出现的,本机运行都好好的,打包构建然后放到别的机器上运行出错。

    这个问题一度也让我很迷茫,如果是路径导致的这个问题,那么把路径指定正确就可以了,但是偏偏路径也是对的,就是报错。那应该是环境问题。

    我为什么要使用ffi调用动态链接库?我的需求是这样的,需要编程实现tcpip方式连接诺德施瓦茨仪表设备cmw500,其实就是visa编程了,我开始通过c语言简单实现了这个功能,以为万事大吉了,然后写了一个动态链接库,让electron项目去调用,因为node方面对visa操作的很少,网上唯一可以搜到的一个链接就是github上的这个:https://github.com/petertorelli/ni-visa。我当时没有细看,也不确定这个方式可不可靠。

    自己写的动态链接库代码:

    pch.h

#ifdef PCH_H
#else 
#define PCH_H extern "C" _declspec(dllimport)

// add headers that you want to pre-compile here
#include "framework.h"

#endif //PCH_H
PCH_H void QueryMeasureResult(char* source,char* cmd,char* result);

    pch.cpp

// pch.cpp: source file corresponding to the pre-compiled header
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE
#endif
#define PCH_H extern "C" _declspec(dllexport)
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "visa.h"
static ViSession defaultRM;
static ViSession instr;
static ViUInt32 retCount;
static ViUInt32 writeCount;
static ViStatus status;
static unsigned char buffer[100];
static char stringinput[512];
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
void QueryMeasureResult(char* source,char* cmd,char* result) {
	status = viOpenDefaultRM(&defaultRM);
	if (status < VI_SUCCESS) {
		viClose(defaultRM);
		strcpy(result, "error");
		return;
	}
	status = viOpen(defaultRM, source,VI_NULL, VI_NULL, &instr);
	if (status < VI_SUCCESS) {
		viClose(defaultRM);
		strcpy(result, "error");
		return;
	}
	status = viSetAttribute(instr, VI_ATTR_TMO_VALUE, 5000);
	status = viSetAttribute(instr, VI_ATTR_ASRL_BAUD, 4800);
	status = viSetAttribute(instr, VI_ATTR_ASRL_DATA_BITS, 8);
	status = viSetAttribute(instr, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_NONE);
	status = viSetAttribute(instr, VI_ATTR_ASRL_STOP_BITS, VI_ASRL_STOP_ONE);
	status = viSetAttribute(instr, VI_ATTR_TERMCHAR_EN, VI_TRUE);
	status = viSetAttribute(instr, VI_ATTR_TERMCHAR, 0xA);
	strcpy(stringinput, cmd);
	status = viWrite(instr, (ViBuf)stringinput, (ViUInt32)strlen(stringinput), &writeCount);
	if (status < VI_SUCCESS) {
		viClose(defaultRM);
		strcpy(result, "error");
		return;
	}
	status = viRead(instr, buffer, 100, &retCount);
	if (status < VI_SUCCESS) {
		strcpy(result, "error");
	}
	else {
		//buffer = "0,2.415445E+001"
		strcpy(result, (const char*)buffer);
	}
	viClose(defaultRM);
}

    后来呢,使用自己编译的动态库操作visa,可以实现,而且本机开发环境没有问题,然后非常高兴的就以为这个问题解决了,打包,后来测试就出了问题,总是报如题所示的错误。

    我的这段代码主要是使用visual studio 2017编译的,当时用c语言测试和node测试都没有问题。

    visatest.js

var ffi = require("ffi")
var ref = require("ref")
var path = require("path")
var dllpath = path.resolve(__dirname,"visademo.dll")
console.log(dllpath)
const api = new ffi.Library(dllpath,{
    QueryMeasureResult:["void",["string","string","string"]]
})
var source="TCPIP0::192.168.253.13::inst0::INSTR";
var cmd = "FETCh:GPRF:MEAS:POWER:PEAK:MAXimum?\n";
var result=Buffer.alloc(100);
result.type = ref.types.char;
api.QueryMeasureResult(source,cmd,result);
var str = result.readCString()
var arr = str.split(",");
var maximum  = arr[1]
console.log(parseFloat(maximum),maximum)

    /以上是我的代码和问题描述部分//

    我以为是因为我的代码本身调用了visa库,如果它不用调用其他库,简单的动态链接库是不是就不会出现这个问题呢?实际上,我同样使用visual studio 2017编译,本机检查都没有问题,放到别的机器上就出问题了。看来问题就出在环境上。

    后来偶然看到一个论坛上说,需要通过npm安装windows-build-tools,我试着在别的机器上安装,发现果然就不再报错了。

    但是这么一来,只要是动态链接库调用,都需要在别的机器上安装这个东西,似乎太扯淡了,其实electron+ffi现在这么成熟了,不可能编写的程序最后还需要在运行机器上再安装一个windows-build-tools。

    其实windows-build-tools安装,本质需要安装一个msbuild,同时安装了python,windows10 sdk,cmake等工具,而windows-build-tools需要下载vs_BuildTools.exe,并启动安装,其实就是使用visual studio install的安装,如果你安装过visual studio 2017的话,对这个非常熟悉。我的环境里面,需要安装上cmake,同时cmake又依赖windows10 sdk,而这个玩意就有2.4G这么大,所以别的系统上如果需要运行不报错的electron+ffi程序,还需要安装大概3G的环境,有些不切实际。

    后来,我又看了一遍前面提到的node环境下操作visa的项目,其实它借助了nivisa1850full安装之后,在系统中生成的visa64.dll依赖库,同样是操作动态链接库,这个项目还有6颗星,我觉着可以一试,抱着试试看的态度,最后发现可以。

    而且别的机器不用安装windows-build-tools环境也可以运行,但是别的机器需要安装nivisa依赖环境,这个是需要操作诺德施瓦茨仪表的。

    比较意外的是,我自己也写了一个动态库,在命令行下编译,没有使用visual studio 2017 ide工具编译,最后打包,在别的机器上使用也没有问题。

    我断定,我的动态链接库调用的问题是出在使用visual studio 2017 ide工具编码编译,至于为什么,我现在还没有搞清楚。我使用命令行编译,其实也是使用的visual studio 2017安装生成的开发人员编译工具,竟然就没有问题。

    

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
### 回答1: 很抱歉,您遇到了"error: failed linking file resources"的错误。这个错误通常是由于在Android项目中缺少某些资源文件或者资源文件引用的路径错误导致的。 以下是一些可能的解决方案: 1. 检查您的布局文件和代码中是否引用了不存在的资源文件。如果有,请添加或者修复资源文件的路径。 2. 检查您的项目中是否有重名的资源文件。如果有,请重命名其中一个以避免冲突。 3. 清理您的项目并重新构建它。在Android Studio中,可以通过点击菜单栏中的"Build" -> "Clean Project"来清理项目。 4. 检查您的gradle文件是否正确配置了所需的依赖项。如果有缺失的依赖项,请在gradle文件中添加它们。 希望这些解决方案能够帮助您解决这个问题。如果问题仍然存在,请提供更多的详细信息,例如具体的错误消息和相关代码,以便更好地帮助您解决问题。 ### 回答2: "error: failed linking file resources" 是 Android 应用开发中常见的错误提示之一。这个错误通常是由于资源文件引用不正确或资源文件被删除导致的。具体而言,可能是以下几种情况: 1. XML 文件中的资源引用有误:在 XML 文件中,如果引用的资源文件不存在或者命名不正确,会导致应用编译失败。因此,检查一下 XML 文件中资源文件的引用是否正确,比如检查一下命名、路径、大小写等。 2. 文件系统中资源文件被删除:有时候我们可能会删除资源文件,但是应用程序中还在引用这些文件,这就会导致这个错误。为了避免这种情况,需要在删除资源文件之前先检查一下应用程序中是否有这些文件的引用,确认无误后再进行删除。 3. Gradle 构建脚本中的错误:Gradle 构建脚本是 Android 应用开发中很重要的一部分,一些资源文件的引用或者路径等相关信息都在构建脚本中定义。如果构建脚本中出现错误,就会导致编译失败。因此,在构建脚本中要特别注意资源文件的引用和路径是否正确。 当遇到这个错误时,我们可以通过以下方法来解决: 1. 检查 XML 文件中资源文件的引用是否正确,重新编辑修正错误的引用。 2. 反编译 APK 文件,检查文件系统中的资源文件是否完整,如有文件缺失需进行补全。 3. 检查 Gradle 构建脚本中的资源文件引用和路径是否正确,如有错误需要修改。 总之,错误提示 "error: failed linking file resources" 是一个比较常见的 Android 应用开发错误,需要我们仔细排查,并根据具体情况来采取不同的解决方法。 ### 回答3: error: failed linking file resources是一种Android Studio常见的错误提示,通常出现在编译布局文件或导入第三方库的时候。 出现这种错误的原因一般是由于引用不存在或不正确、缺少依赖包或使用了过时的依赖包、Android SDK不兼容或配置不正确等原因。 解决这种错误需要根据具体情况去调整配置,以下是一些常见的解决办法: 1.检查依赖包是否存在或版本是否正确,可以在build.gradle文件中添加依赖包或另行下载依赖包。 2.检查Android SDK是否安装完整或版本是否过低,可以更新SDK或调整配置信息。 3.在代码中避免使用不兼容的方法或类,例如可以使用AndroidX替代旧版Support Library。 4.尝试清除缓存或重新启动Android Studio软件。 总之,解决error: failed linking file resources错误需要有耐心和准确的判断能力,需要根据具体情况进行调试和修复,有效的解决了这种错误可以让应用更加稳定和安全。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

luffy5459

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

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

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

打赏作者

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

抵扣说明:

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

余额充值