为了账号安全,请及时绑定邮箱和手机立即绑定

使用 LoadLibraryA(path_to_dll) 加载 DLL 会将文件描述符

使用 LoadLibraryA(path_to_dll) 加载 DLL 会将文件描述符

Go
慕少森 2022-12-05 16:24:39
我们已经用 golang 和 ac wrapper 编写了一些函数来调用这些函数。我们首先构建 golang 代码来创建一个存档文件,然后我们在 c 中构建包装器代码以作为 DLL 使用。在我的程序中使用 LoadLibraryA(path_to_dll) 加载此 DLL 后,我看到 fd 0、1 和 2 的继承标志从 1 更改为 0。但这不会在加载 DLL 后立即发生。我在加载库调用后在我的代码中添加了睡眠,似乎在加载库后需要几毫秒才能更改标志值。我正在使用 GetHandleInformation((HANDLE) sock, &flags) 来获取继承标志值。关于可能导致此问题的任何想法/指示?谢谢!更新: 我能够在 go 代码中找到翻转继承标志值的确切行。以下 k8sService.go 代码中的全局变量 reqHandler 导致了此问题。知道为什么使用这个全局变量会翻转继承标志值吗?my-lib/k8sService.go(go代码)package mainimport "C"import (    "my-lib/pkg/cmd")func main() {}var reqHandler []*cmd.K8sRequest我的库/pkg/cmd/execute.goimport (    "my-lib/pkg/dto")type K8sRequest struct {    K8sDetails dto.K8sDetails}my-lib/pkg/dto/structs.gopackage dto// K8sDetails contains all the necessary information about talking to the cluster. Below struct has few more variables.type K8sDetails struct {    // HostName of the cluster's API server    HostName string `json:"hostname"`    // Port on which the API server listens on to    Port int `json:"port"`}我们在上面的 k8sService.go 之上有一个 C 包装器。我们首先构建 golang 代码来创建一个存档文件,然后使用这个存档文件和 C 中的包装器代码构建目标 DLL。下面是加载此 DLL 并在加载 DLL 前后打印继承标志值的示例程序。#include <windows.h>#include <iostream>#include <io.h>#include "wrapper/cWrapper.h"void printInheritVals() {        typedef SOCKET  my_socket_t;        my_socket_t fd0 = _get_osfhandle(0);        my_socket_t fd1 = _get_osfhandle(1);        my_socket_t fd2 = _get_osfhandle(2);        std::cout << "fd0: " << fd0 << std::endl;        std::cout << "fd1: " << fd1 << std::endl;        std::cout << "fd2: " << fd2 << std::endl;                        DWORD flags;        int inherit_flag_0 = -1;        int inherit_flag_1 = -1;        int inherit_flag_2 = -1;
查看完整描述

1 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

这是golang.org/x/sys/windows包中的错误。同样的问题过去也存在于内置的 syscall 包中,但它在 Go 1.17 中得到了修复

您项目中的某些内容必须导入包的 golang.org/x 版本而不是内置版本,因此执行以下代码来初始化StdinStdoutStderr变量:

var (

    Stdin  = getStdHandle(STD_INPUT_HANDLE)

    Stdout = getStdHandle(STD_OUTPUT_HANDLE)

    Stderr = getStdHandle(STD_ERROR_HANDLE)

)


func getStdHandle(stdhandle uint32) (fd Handle) {

    r, _ := GetStdHandle(stdhandle)

    CloseOnExec(r)

    return r

}

该代码的修复方法是删除CloseOnExec调用,这是HANDLE_FLAG_INHERIT在给定文件句柄上清除的内容。

如何在你的项目中解决这个问题还不太清楚。我想你可以在你的项目中供应 golang.org/x/sys模块,也许replace在你的 go.mod 中有一个指令。在您的本地副本中应用修复程序。

同时,我鼓励您也报告该错误。该文档指示您在 GitHub 的主要 Go 项目上报告问题,并在标题前加上x/sys前缀。



查看完整回答
反对 回复 2022-12-05
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信