什么c#类型代表c++ float* ?

本文关键字:float c++ 类型 什么 | 更新日期: 2023-09-27 18:04:00

我有一个从c++库中调用的函数,该函数已导入到c#项目

我认为它要求一个指向数组的指针。但我不知道如何使它工作。

这是它要求的function(float*, float*);

但是如果我输入

float[] f = {};
float[] f1 = {};
function(f,f1);

显示有无效参数

什么c#类型代表c++ float* ?

float *是c#中的浮点指针类型。

如果函数需要浮点型指针实参(float *),则必须假定该函数处理指针,可能涉及指针算术。因此,保留该签名非常重要。

要在c#中将浮点数组作为浮点指针(float*)传递,需要在不安全的上下文中将数组固定在内存中,以获取指向它们的指针,然后传递给函数以保持其功能:

unsafe
{
    fixed (float* ptr_f = f) //or equivalently "... = &f[0]" address of f[0]
    fixed (float* ptr_f2 = f2) //or equivalently "... = &f2[0]" address of f2[0]
    {
        function( ptr_f, ptr_f2 );
    }
}

您还需要将程序集标记为不安全(在项目属性>构建选项卡>允许不安全代码复选框中)。

如果这是通过DLLImport()导入的方法,您可以简单地将数组指针替换为类型数组。

所以签名:

[DLLImport("some.dll")]
SomeMethod(int* a, float* b)

[DLLImport("some.dll")]
SomeMethod(int[] a, float[] b)

请注意,这是假设原始c/c++方法期望一个数组。

您需要确切地知道被调用的c++函数期望的是什么。

在C(和c++)中,所有这些函数签名的意图和目的都是完全相同的:

void foo( float *x   , float *y   ) ;
void foo( float *x   , float  y[] ) ;
void foo( float  x[] , float *y   ) ;
void foo( float  x[] , float  y[] ) ;

它们都有2个参数,每个参数包含一个指向float类型变量的指针(包含地址)。所有这些表达式在C/c++中是完全相同的:

float x[] ;
float *y  ;
float r1 = *(x+37) ; // all evaluate to the zero-relative
float r2 = x[37]   ; // 37th element of the array.
float r3 = *(y+37) ;
float r4 = y[37]   ;
  • 表达式*x表示,"获取位于x中包含的地址的float(4字节)。
  • 表达式*(x+n),其中n是一个整数值,表示"取x中包含的地址,并将表达式sizeof(float) * n获得的偏移量(以字节为单位)添加到x中。"获取结果地址处的float值。
  • 数组表达式x[n]与指针表达式*(x+n)完全等价。

由于C/c++中的数组没有任何描述其大小的相关元数据,因此您需要确切地知道被调用函数的期望。

通常,传递一个指针(按引用调用)是为了允许调用者对该点解引用并为你设置一个值。相当于c#的refout关键字:

float x ;
float y ;
Foo( ref x , ref y ) ; // the callee MAY, but is not REQUIRED to set a value before returning to the caller.
Bar( out x , out y ) ; // the callee MUST set a value before returning to the caller.

您的函数使用的习惯用法总是用于定位数组,但通常也会传递大小:

void foo( float *array , int array_length ) ;

虽然这并不罕见,但如果函数期望数组是一个非零数值列表,则应该是类似于c风格的以空结束的字符串。给定函数签名,例如:

float compute_mean( float *Xs ) ;

这样调用它是很正常的:

float Xs[] = { 3.0 , 2.5 , 9.8 , 7,5 , 0 , } ;
float mean = compute_mean( Xs ) ;

和定义类似于:

float compute_mean( float *Xs )
{
  float n   = 0.0 ;
  float sum = 0.0 ;
  float mean ;
  while ( *p )
  {
    ++n ;
    sum += *p++ ;
  }
  mean = n > 0 ? sum / n : 0.0 ;
  return mean ;
}

所以你需要知道你调用的方法的语义。

在c#中根本不起作用,当在c#中导入C/c++库时,您应该使用IntPtr而不是float*,参见这里的一些示例:

请求一个浮点指针(内存中包含IEEE浮点值的点的机器地址)。c#不允许指针的托管使用,所以你需要构造一个IntPtr变量并将其传递给c++函数。

注意:仅仅因为它被称为IntPtr并不意味着它只是一个指向整数的指针。Int是因为所有指针都是整型。它可以是指向任何东西的指针。