结合C和C#。结构' S

时间:2017-02-28 16:33:07

标签: c# c casting wrapper

我需要帮助,我有一个C结构:

struct Connection 
{
    int From;
    int To;
    double Weight;
};

struct Node
{
    int ID;
    double Value;
};

struct ListElement
{
    ListElement *next;
    void *element;
};

struct NeuroNet
{
    ListElement *nodes;
    ListElement *connections;
    int inputs;
    int outputs;
};

有一些功能(如传球和那种东西)。 (整个ide就是提高单线程性能)

我需要在C#代码中使用这个神经网络功能,但问题就出现了:我通过C#教这个神经网络(改变重量),我想直接改变字段'连接结构的s,并使用foreach类的通道,样本:

foreach(var c in WrapperClassName.GetConnections()) {
... 
    c.Weight = c.Weight + 0.3 / someCSvariable;
...}

WrapperClassName.ForEachConnection(x => { 
...
    x.Weight = x.Weight + 0.3 / someCSvariable;
... });

所以,我该怎么做?

有没有办法将C指针放在C#类的结构上(因为它是ref var)?

2 个答案:

答案 0 :(得分:1)

您似乎正在尝试将C#中的链接列表传递给C.这意味着您需要使用Interop服务。看一下StructLayoutAttribute类。您还需要使用IntPtr定义指针。

以下是将其用于其中一个结构的示例:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Connection 
{
   public Int32 From;
   public Int32 To;
   public Double Weight;
};

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct ListElement{ 
  public IntPtr next;
  public IntPtr element; 
};

我喜欢找到我的互操作问题的答案的方法是查找已经定义的类似结构。我通常使用pinvoke.net来查找它们。以下是IP_ADDR_STRING的示例,它是IP地址的链接列表。

答案 1 :(得分:1)

无法将C指针强制转换为C#引用,因为C对象将位于非托管内存中,而C#对象将位于托管内存中。

我认为实现目标的最佳方法是使用VC ++,它具有在同一程序集中混合非托管代码和托管代码的独特功能。因此,您可以将非托管C结构传递给托管C ++方法,并使用类似C#的语法。托管VC ++方法可以调用C#或被C#调用,所以如果你真的想用C#做事,这可能是一种方式。

当然还有其他方法可以连接C和C#,例如,您可以使用DllImport将C#连接到C函数。当您调用该函数时,必须使用名为marshalling的工具将参数传送到非托管内存或从非托管内存传送。对于常见类型(如int,double和even struct),编组很简单,但对于需要考虑对齐的结构来说要复杂得多......你需要完成这项工作的麻烦根本不值得图。

所以我的建议是给VC ++一个机会。