当我将一个int64类型的数字传递给函数时,返回了一个不同的数字。

huangapple go评论71阅读模式
英文:

When I write an int64 type number to the function, a different number is returned

问题

我将golang代码转换为C代码,并从Python中调用它。但是当函数应该返回一个接近我输入的数字时,它返回一个非常不同的数字。

main.py

import ctypes

library = ctypes.cdll.LoadLibrary('./maintain.so')
hello_world = library.helloWorld
numb = 5000000000
n = ctypes.c_int64(numb)
x = hello_world(n)
print(x)

返回的数字是705032703。

我将golang代码转换为C代码如下:

main.go

package main

import "C"

func helloWorld(x int64) int64 {
    s := int64(1)
    for i := int64(1); i < x; i++ {
        s = i
    }
    return s
}
英文:

I converted the golang code to c code and called it from python. but when the function should return a number close to the number I wrote inside, it returns a very different number.

main.py

import ctypes

library = ctypes.cdll.LoadLibrary(&#39;./maintain.so&#39;)
hello_world = library.helloWorld
numb = 5000000000
n = ctypes.c_int64(numb)
x = hello_world(n)
print(x)

returning number: 705032703

golang code that I converted to c code

main.go

package main

import &quot;C&quot;

func helloWorld(x int64) int64 {
	s := int64(1)
	for i := int64(1); i &lt; x; i++ {
		s = i
	}
	return s
 }

答案1

得分: 3

你犯了99%新的ctypes用户都会犯的错误:没有声明所使用函数的参数类型和返回类型。ctypes默认将标量参数视为c_int,指针参数视为c_void_p,返回类型默认为c_int,除非另有说明。如果你定义了它们,你就不需要将每个参数都包装在你想要传递的类型中,因为ctypes已经知道了。

我无法为Go设置,但这是一个带有64位参数和返回类型的简单C实现的函数:

#include <stdint.h>

#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

API int64_t helloWorld(int64_t x) {
        return x + 1;
}

调用它的Python代码:

import ctypes as ct

dll = ct.CDLL('./test')
dll.helloWorld.argtypes = ct.c_int64,  # 参数类型的序列
dll.helloWorld.restype = ct.c_int64    # 返回类型

# 注意,你不需要将参数包装起来,比如c_int64(5000000000)。
print(dll.helloWorld(5_000_000_000))

输出:

5000000001
英文:

You're making the mistake 99% of new ctypes users: not declaring the argument types and return type of the function used. ctypes assumes c_int for scalars and c_void_p for pointers on arguments and c_int for return type unless told otherwise. If you define them, you don't have to wrap every parameter in the type you want to pass, because ctypes will already know.

I'm not set up for Go, but here's a simple C implementation of the function with a 64-bit argument and return type:

#include &lt;stdint.h&gt;

#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

API int64_t helloWorld(int64_t x) {
        return x + 1;
}

The Python code to call it:

import ctypes as ct

dll = ct.CDLL(&#39;./test&#39;)
dll.helloWorld.argtypes = ct.c_int64,  # sequence of argument types
dll.helloWorld.restype = ct.c_int64    # return type

# Note you don&#39;t have to wrap the argument, e.g. c_int64(5000000000).
print(dll.helloWorld(5_000_000_000))

Output:

5000000001

huangapple
  • 本文由 发表于 2022年8月18日 22:37:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/73404950.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定