Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么样的C#type代表C++;浮动*? 我有一个函数,它从C++中的一个库中调用,它已经被导入到一个C项目中_C# - Fatal编程技术网

什么样的C#type代表C++;浮动*? 我有一个函数,它从C++中的一个库中调用,它已经被导入到一个C项目中

什么样的C#type代表C++;浮动*? 我有一个函数,它从C++中的一个库中调用,它已经被导入到一个C项目中,c#,C#,我认为它需要一个指向数组的指针。但我不知道该怎么做 下面是它所要求的函数(float*,float*) 但如果我做了类似的事情 float[] f = {}; float[] f1 = {}; function(f,f1); 它表示有无效的参数。< p>这在C++中是不起作用的,当导入C中的C/C++库时,你应该使用 int pTr> /COD>而不是浮点*,请参阅这里的一些例子: < P>它要求一个浮点指针,即内存中包含IEEE浮点值的一个点的机器地址。C++不允许使用指针,因此需要构造变

我认为它需要一个指向数组的指针。但我不知道该怎么做

下面是它所要求的
函数(float*,float*)

但如果我做了类似的事情

float[] f = {};
float[] f1 = {};

function(f,f1);

它表示有无效的参数。

< p>这在C++中是不起作用的,当导入C中的C/C++库时,你应该使用<代码> int pTr> /COD>而不是浮点*,请参阅这里的一些例子:

< P>它要求一个浮点指针,即内存中包含IEEE浮点值的一个点的机器地址。C++不允许使用指针,因此需要构造变量并将其传递给C++函数。p>
注意:仅仅因为它被称为
IntPtr
,并不意味着它只是一个指向整数的指针。Int是因为所有指针都是整数。它可以是指向任何东西的指针

如果这是通过
DLLImport()
导入的方法,只需将数组指针替换为类型化数组即可

因此,签名:

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

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

请注意,这假设原始c/c++方法需要一个数组。如果指针不用于引用数组,这将不起作用。

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 );
    }
}

您还需要将程序集标记为不安全(在ProjtualProjks> Bu建Tabe>允许不安全代码复选框)。

< P>您需要确切知道调用的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[] ) ;
它们都有两个参数,每个参数都包含一个指向
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
    中包含的地址处的
    浮点值(4字节)
  • 表达式
    *(x+n)
    ,其中
    n
    是一个整数值,表示“取x中包含的地址,并将表达式
    sizeof(float)*n所获得的字节偏移量相加。获取位于结果地址的
    float
  • 数组表达式
    x[n]
    与指针表达式
    *(x+n)
    完全等效
而且,由于C/C++中的数组没有任何描述其大小的关联元数据,因此您需要确切地知道被调用函数的期望值

通常,传递指针(通过引用调用)以允许调用方取消引用该点并为您设置一个值-相当于C#的
ref
out
关键字:

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 ) ;
尽管这并不罕见,但如果函数希望数组是非零数值的列表,则类似于以NUL结尾的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#是一种托管语言。C#不允许托管使用指针?您可以在托管(不安全)代码中使用它们,甚至可以将它们传递给非托管DllImported函数…更清楚地说。。。保留签名需要对代码进行最少的更改,但如果您希望避免不安全的上下文和低效的内存固定,只需将浮点指针(float*)参数转换为更安全的浮点数组(float[])参数类型并检查函数的逻辑,以确保没有诸如f++或f+=4之类的指针算法或类似(*(f+4))的解引用。如果浮点指针是通过数组索引(如f[i])访问的,那么在C#中访问数组的语法是相同的,这只是风格上的差异,请参见Upvote。我也回答了,假设OP正在将源代码导入C#项目(不是很清楚),但如果是p-invoke调用。。。这适用于简单类型。CLR将在函数调用期间自动固定对托管数组的引用(尽管要小心尝试缓存托管指针的函数):。需要更多注意复杂类型(如字符串、结构和多维数组)的编组,例如编组是否需要复制到非托管内存和/或从非托管内存复制,以及是否需要进行任何转换(例如,从unicode到ANSI字符串)。它取决于类型是否为“blittable”,以及是否在参数上指定属性,如MarshalAs、In或Out(或使用“Out”或“ref”关键字暗示In或Out属性)。见:和。