我们已经在golang中编写了一些函数,并在此基础上编写了一个c包装器来调用这些函数.我们首先构建golang代码来创建一个归档文件,然后用c语言构建包装器代码,作为DLL使用.

在我的程序中使用LoadLibraryA(path_to_DLL)加载这个DLL之后,我看到fd 0、1和2的继承标志从1更改为0.不过,加载DLL后不会立即发生这种情况.在加载库调用之后,我在代码中添加了sleep,似乎在加载库之后需要几毫秒来更改标志值.

我正在使用GetHandleInformation((HANDLE)sock,&标志)以获取继承标志值.

有什么 idea /建议是什么导致的吗?谢谢

Updates:

我的lib/K8S服务.go(go代码)

package main

import "C"
import (
    "my-lib/pkg/cmd"
)

func main() {
}

var reqHandler []*cmd.K8sRequest

我的lib/pkg/cmd/execute.go

import (
    "my-lib/pkg/dto"
)

type K8sRequest struct {
    K8sDetails dto.K8sDetails
}

我的lib/pkg/dto/structs.go

package 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"`
}

我们在上面的K8S服务上有一个C包装.go 我们首先构建golang代码来创建一个归档文件,然后用这个归档文件和C语言中的包装器代码来构建目标DLL.下面是加载此DLL的示 routine 序,并在加载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;
        

        if (!GetHandleInformation((HANDLE) fd0, &flags)) {
            std::cout << "GetHandleInformation failed" << std::endl;
        } else {
            inherit_flag_0 = (flags & HANDLE_FLAG_INHERIT);
        }

        if (!GetHandleInformation((HANDLE) fd1, &flags)) {
            std::cout << "GetHandleInformation failed" << std::endl;
        } else {
            inherit_flag_1 = (flags & HANDLE_FLAG_INHERIT);
        }

        if (!GetHandleInformation((HANDLE) fd2, &flags)) {
            std::cout << "GetHandleInformation failed" << std::endl;
        } else {
            inherit_flag_2 = (flags & HANDLE_FLAG_INHERIT);
        }
        
        std::cout << "inherit_flag_0: " << inherit_flag_0 << std::endl;
        std::cout << "inherit_flag_1: " << inherit_flag_1 << std::endl;
        std::cout << "inherit_flag_2: " << inherit_flag_2 << std::endl;
}

int main()
{

    printInheritVals(); // In output all flag values are 1
    HINSTANCE hGetProcIDDLL = LoadLibraryA(PATH_TO_DLL);
    if (!hGetProcIDDLL) {
        std::cout << "could not load the dynamic library" << std::endl;
        return EXIT_FAILURE;
    }
    std::cout << "Library loaded" << std::endl;
    printInheritVals(); // In output all flag values are 1
    Sleep(1000);
    printInheritVals(); // In output all flag values are 0
    return EXIT_SUCCESS;
}

推荐答案

这是golang.org/x/sys/windows软件包中的一个错误.同一期used to be in the built-in syscall package as well,但它是fixed in 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.

如何在项目中解决这个问题还不太清楚.我认为你可以在你的项目中使用vendorgolang.org/x/sys模块,也许你可以使用replace指令.摩登派青年在本地副本中应用修复程序.

同时,我鼓励你们也报告这个错误.The documentation指示您在main Go project at GitHub上报告问题,标题前加x/sys.

Go相关问答推荐

杜松子wine -戈尼克背景在 children 围棋例行公事中被取消

Go程序在并发Forking 循环中停留在syscall.Wait4

难以为多个平台添加Go Bazel构建选项

CGO Linux到Windows交叉编译中的未知类型名称

map 中的多个函数类型,Golang

带有一个新变量的Go冒号等于运算符

通过代理从golang连接到ftp

Go 中将 int 切片转换为自定义 int 切片指针类型的函数

Go-如何在递归函数中关闭通道

在 go 中,将接收器 struct 从值更改为指针是否向后兼容?

如何使用gosdk在Dynamodb中进行UpdateItem时,将ValueBuilder对象声明为StringSet类型?

Opensearch 错误 ping 弹性服务器:由未知权威签署的 x509 证书

Golang 创建一个带有处理程序的模拟数据库并使用接口调用数据库

如何判断范围内的字段?

Golang:如何判断通过缓冲通道进行通信时生产者或消费者是否较慢?

如何使用带有方法的字符串枚举作为通用参数?

Go 中的 HTTP 请求验证中间件

在 docker kill --signal=SIGX 上以这种方式关闭容器内运行的 go 应用程序是否安全?

级联调用泛型函数时的泛型类型推断

Golang 有类似 C++ 的 decltype 的东西吗?