基本上,我有一个C函数,可以打印出某些数字,并且我还希望该函数返回2个值。我已经使用struct
进行了尝试,但是操作不正确,并且不确定如何继续。我已经阅读了其他问题,并且我知道使用指针会更好,但是我不确定该怎么做。
我的C代码如下:
struct re_val
{
double predict_label;
double prob_estimates;
predict_label = 5.0;
prob_estimates = 8.0;
};
int c_func(const char* dir, double a, double b, double c, double d)
{
double x[] = { a, b, c, d };
printf("x[0].index: %d \n", 1);
printf("x[0].value: %f \n", x[0]);
printf("x[1].index: %d \n", 2);
printf("x[1].value: %f \n", x[1]);
printf("x[2].index: %d \n", 3);
printf("x[2].value: %f \n", x[2]);
printf("x[3].index: %d \n", 4);
printf("x[3].value: %f \n", x[3]);
return re_val;
}
最终,我只想调用一个能够打印出数组并返回predict_label
和prob_estimates
的函数。
我实际上是通过ctypes在python中调用此函数的,以下是我的python函数。
calling_function = ctypes.CDLL("/home/ruven/Documents/Sonar/C interface/Interface.so")
calling_function.c_func.argtypes = [ctypes.c_char_p, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double]
calling_function.c_func.restype = ctypes.c_double
y = calling_function.c_func("hello",1.1, 2.2, 3.1, 4.2)
print y
答案 0 :(得分:3)
首先,您需要定义结构:
struct re_val{
float predict_label;
float prob_estimates;
};
然后您需要从函数中返回一个struct re_val
:
struct re_val c_func(const char* dir, float a, float b, float c, float d )
{
/* ... all that stuff ... */
struct re_val r;
r.predict_label = 5.0f;
r.prob_estimates = 8.0f;
return r;
}
因此,完整的示例将是:
struct re_val{
float predict_label;
float prob_estimates;
};
struct re_val c_func(const char* dir, float a, float b, float c, float d )
{
/* ... all that stuff ... */
struct re_val r;
r.predict_label = 5.0f;
r.prob_estimates = 8.0f;
return r;
}
int main(void)
{
struct re_val r = c_func("",1.0f,2.0f,3.0f,4.0f);
printf("predict_label=%.1f\n",r.predict_label);
printf("predict_label=%.1f\n",r.prob_estimates);
return 0;
}
答案 1 :(得分:2)
这通常是通过结构来完成的。要将其初始化在堆栈上,请执行以下操作。
#include <stdio.h> /* printf */
#include <assert.h> /* assert */
struct sample {
float x[4];
};
struct re_val {
float predict_label, prob_estimates;
};
/** Returns the re_val of x. */
static struct re_val c_func(const struct sample *const x) {
struct re_val rv;
float a;
assert(x); /* Debug warn if called with null. */
rv.predict_label = (x->x[0] + x->x[1]) * 5.0f;
a = x->x[2] + x->x[3];
if(a < 0.01f) a = 0.01f;
rv.prob_estimates = 1.0f / a;
return rv;
}
/** Prints the re_val. */
static void print(const struct re_val *const rv) {
assert(rv);
printf("# prediction label\tprobability estimates\n%g\t%g\n",
rv->predict_label, rv->prob_estimates);
}
int main(void) {
const struct sample x = { { 0.1f, 0.2f, 1.0f, 100000.0f } };
const struct re_val rv = c_func(&x);
print(&rv);
return 0;
}
查看此链接Are there any downsides to passing structs by value in C, rather than passing a pointer?;具体来说,原型可能是在static void c_func(const struct sample *const x, struct re_val *const rv);
处填充了rv
指针的地方,尤其是在re_val
是一个大结构或希望将其潜在地分配到堆上的情况下。
有多种方法可以将信息从函数中传递出去,例如,
div
,strtod64
; fread
,fscanf
,snprintf
,sprintf
,strfmon
,strncat
,strncpy
,strptime
,{{ 1}},strftime
,asctime_r
,ctime_r
; localtime_r
-此方法不会再次进入,并且会多次覆盖相同的数据。它不是线程安全的。 static struct
,asctime
,ctime
,gmtime
,localtime
; strtok
:FILE *
/ fopen
,fclose
:regex_t
/ { {1}}或全局regcomp
:regfree
; errno
。答案 2 :(得分:1)
此答案是使用结构的替代方法-这当然是有效的-您可以通过引用/通过指针返回多个值。并回答了主要问题,即是否可以从单个函数返回多个值。
#include<stdio.h>
void sum_diff(double a, double b, double* sum, double*diff)
{
if (sum) // Only assign when we have a valid reference
*sum = a + b;
if (diff)
*diff= a - b;
}
int main() {
double diff, sum;
double a = 4, b = 3;
sum_diff(a, b, &sum, &diff);
fprintf(stdout, "The sum of %lf and %lf is %lf\n", a, b, sum);
fprintf(stdout, "The difference of %lf and %lf is %lf\n", a, b, diff);
return 0;
}
sum_diff
分配的函数使用参数a
,b
,sum
和diff
。 a
和b
是输入参数,sum
和diff
是输出参数。请注意,该函数检查sum和diff是否为NULL,这使调用方可以选择获取差值或sum。使用更多的计算密集型计算可能会很方便。