C++ cli 通过托管C++;与非托管C之间的数组 我是C、C++和C++/CLI的初学者,我对指针和东西不太了解,但我确实需要在C库中创建.NET包装器。我试过使用SWIG,但它不起作用,我被卡住了。我不想使用P/Invoke,因为其中涉及到一些嵌套结构,而且我了解到P/Invoke对这些结构不是很好

C++ cli 通过托管C++;与非托管C之间的数组 我是C、C++和C++/CLI的初学者,我对指针和东西不太了解,但我确实需要在C库中创建.NET包装器。我试过使用SWIG,但它不起作用,我被卡住了。我不想使用P/Invoke,因为其中涉及到一些嵌套结构,而且我了解到P/Invoke对这些结构不是很好,c++-cli,C++ Cli,总之,我有一个C头,看起来像这样: // packer.h typedef struct { int left; int top; int right; int bottom; } frame_t; typedef struct { /* IN */ int width; int height; /* OUT */ frame_t view; frame_t dest; } image_t; typedef st

总之,我有一个C头,看起来像这样:

// packer.h
typedef struct {
    int left;
    int top;
    int right;
    int bottom;
} frame_t;

typedef struct {
    /* IN */
    int width;
    int height;
    /* OUT */
    frame_t view;
    frame_t dest;
} image_t;

typedef struct {
    int page_width;
    int page_height;
    int margin;
    int nb_run;
} parameters_t;

int pack(image_t *images, int nb_images, parameters_t params);
在这里和那里使用各种教程和帮助信息,我已经开始围绕以下内容编写C++/CLI包装器:

// packer_cli.cpp
#include <windows.h>
#include <vcclr.h>
#include "../../packer/packer.h"
#using <System.dll>
#using <mscorlib.dll>

using namespace System;

namespace Packer {
    // re-create the needed structs as managed classes
    public ref class Frame {
    public:
        int Left, Top, Right, Bottom;
    };
    public ref class Image {
    public:
        int Width, Height;
        Frame ^View, ^Dest;
        Image() {
            View = gcnew Frame();
            Dest = gcnew Frame();
        }
    };
    public ref class Parameters {
    public:
        int PageWidth, PageHeight, Margin, NbRun;
    };

    // wrap the main method in a class
    public ref class Packer {
    private:
        int _nb_images;
    public:
        Packer(int nb_images) {
            _nb_images = nb_images;
        }
        int Pack(array< Image^ >^ images, Parameters^ params) {
            // create a native array of image_t to send to the C library
            array< image_t * >^ nativeImages = gcnew array< image_t * >(_nb_images);
            for(int i = 0; i < _nb_images; i++) {
                image_t nativeImage;
                nativeImage.width = images[i]->Width;
                nativeImage.height = images[i]->Height;
                nativeImages[i] = &nativeImage; // is this even how it should be done?
            }

            // HALP!

            // create a native parameters_t to send to the C library
            parameters_t nativeParams;
            nativeParams.page_width = params->PageWidth;
            nativeParams.page_height = params->PageHeight;
            nativeParams.margin = params->Margin;
            nativeParams.nb_run = params->NbRun;

            // call the packing method
            int result = pack(nativeImagesToPass, _nb_images, nativeParams);

            // re-loop on images to get the values from native images, and assign them to managed images
            for(int i = 0; i < _nb_images; i++) {
                // TODO
            }

            return result;
        }
    };
}
并使用
marshall::Copy
。。。嗯,我找不到如何申报我的东西:

System::Runtime::InteropServices::Marshal::Copy(IntPtr((void *)nativeImagesToPass ), nativeImages, 0, _nb_images);
// How do I declare the nativeImagesToPass variable to copy to?
// image_t nativeImagesToPass[_nb_images] yeilds a bunch of errors: C2057, C2466, C2082 and C2133
那么,如何将结构数组从托管数组复制到非托管数组?或者有更好更简单的解决方案?正如我所说,我对C/C++几乎一无所知,所以我真的迷路了

谢谢

更新 感谢@metacubed,我修改了
Pack
方法,如下所示:

int Pack(array< Image^ >^% images, Parameters^ params) {
    // create a native array of image_t to send to the C library
    image_t* nativeImages = new image_t[_nb_images];
    for(int i = 0; i < _nb_images; i++) {
        image_t nativeImage = images[i]->ToNative();
    }

    // call the packing method
    int result = pack(nativeImages, _nb_images, params->ToNative());

    // re-loop on images to get the values from native images, and assign them to managed images
    for(int i = 0; i < _nb_images; i++) {
        images[i]->View = gcnew Frame(nativeImages[i].view);
        images[i]->Dest = gcnew Frame(nativeImages[i].dest);
    }

    delete[] nativeImages;

    return result;
}
int-Pack(数组^%图像、参数^params){
//创建要发送到C库的映像的本机数组
image_t*nativeImages=新图像[u nb_images];
对于(int i=0;i<\u nb\u图像;i++){
image_t nativeImage=images[i]>ToNative();
}
//调用打包方法
int result=pack(nativeImages,_nb_images,params->ToNative());
//重新循环映像以从本机映像获取值,并将其分配给托管映像
对于(int i=0;i<\u nb\u图像;i++){
images[i]->View=gc新帧(nativeImages[i].View);
images[i]->Dest=gc新帧(nativeImages[i].Dest);
}
删除[]个本地图像;
返回结果;
}
但是现在我有这些构建错误(我不确定它们是否相关):

LNK2028:unresolved token(0A000028)“int\u cdecl pack(struct image\u t*,int,struct parameters\u t)”(?pack@$$FYAHPAUimage\u t@@HUparameters\u t@@@Z)在函数“public:int\u clrcall Packer::Packer::pack(cli::array^,class Packer::parameters^)”中引用(?Pack@Packer@1@$$FQ$AAMHA$CAP$01AP$AAVImage@1@P$AAVParameters@1@@Z)
LNK2019:函数“public:int\u clrcall Packer::Packer::pack(cli::array^,class Packer::parameters^)”中引用的未解析外部符号“int\uu cdecl pack(struct image\u t*,int,struct parameters\u t)”(?pack@$$$FYAHPAUimage\u t@@HUparameters\u t@@@Z)(?)?Pack@Packer@1@$$FQ$AAMHA$CAP$01AP$AAVImage@1@P$AAVParameters@1@@Z)

我感觉离目标如此之近,却又如此之远
    int Pack(array< Image^ >^ images, Parameters^ params)
    {
        // create a native array of image_t to send to the C library
        image_t* arrNativeImages = new image_t[_nb_images];
        for(int i = 0; i < _nb_images; i++)
        {
            arrNativeImages[i].width = images[i]->Width;
            arrNativeImages[i].height = images[i]->Height;
        }

        ...

        int result = pack(parrNativeImages[0], _nb_images, nativeParams);

        // Use OUT params from arrNativeImages[i]
        ...

        // Finally don't forget to delete the created array...
        delete[] arrNativeImages;
        arrNativeImages = NULL;
    }
int-Pack(数组^图像、参数^params)
{
//创建要发送到C库的映像的本机数组
image_t*arrantiveimages=新图像[u nb_images];
对于(int i=0;i<\u nb\u图像;i++)
{
arrNativeImages[i].width=图像[i]->width;
arrNativeImages[i].高度=图像[i]->高度;
}
...
int result=pack(parrNativeImages[0],_nb_images,nativeParams);
//使用ArrantiveImage中的参数[i]
...
//最后,不要忘记删除创建的数组。。。
删除[]个ArrantiveImage;
arrNativeImages=NULL;
}

就这么简单。还有其他方法可以直接将托管对象发送到本机代码中,但它们需要结构对齐,以便跨托管结构和本机结构进行匹配。但对于您的情况,这种方法似乎已经足够了。

谢谢,太棒了!但是现在我得到了另一个构建错误:((不确定是否相关…)这些是链接器错误。它们与代码无关。您需要提供包含本机
pack
实现的库和DLL作为项目的参考。您的更新中也有错误。
images[I]->ToNative()
应该分配给
nativeImages[i]
。分配给
nativeImage
变量是一个错误。
pack
函数所在的C文件已经包含在项目中。我已经尝试在其他依赖项中添加指向.lib的链接,但没有修复它。哦,是的,你的错误就在这里!:)我已经开始了修改,但没有完成它…编译器假设包()是用C++编写的。您必须在#include周围使用
extern“C”{}
,以使它确信它实际上是C代码。在前面使用#pragma managed(push,off)和在后面使用#pragma managed(pop)通常也是明智的。不要忘记链接C库。解决链接器错误需要完全不同的信息。最好结束这个问题,用新的细节开始另一个问题。太棒了,谢谢!布拉格语的意思是什么?想在回答中详细说明吗?:)C源代码已经在项目中,我还需要添加链接吗?(编辑:没关系,我会用谷歌搜索)@metacubed:你说得对,我应该:)
LNK2028: unresolved token (0A000028) "int __cdecl pack(struct image_t *,int,struct parameters_t)" (?pack@@$$FYAHPAUimage_t@@HUparameters_t@@@Z) referenced in the function "public: int __clrcall Packer::Packer::Pack(cli::array<class Packer::Image ^ >^,class Packer::Parameters ^)" (?Pack@Packer@1@$$FQ$AAMHA$CAP$01AP$AAVImage@1@P$AAVParameters@1@@Z)
LNK2019: unresolved external symbol "int __cdecl pack(struct image_t *,int,struct parameters_t)" (?pack@@$$FYAHPAUimage_t@@HUparameters_t@@@Z) referenced in the function "public: int __clrcall Packer::Packer::Pack(cli::array<class Packer::Image ^ >^,class Packer::Parameters ^)" (?Pack@Packer@1@$$FQ$AAMHA$CAP$01AP$AAVImage@1@P$AAVParameters@1@@Z)
    int Pack(array< Image^ >^ images, Parameters^ params)
    {
        // create a native array of image_t to send to the C library
        image_t* arrNativeImages = new image_t[_nb_images];
        for(int i = 0; i < _nb_images; i++)
        {
            arrNativeImages[i].width = images[i]->Width;
            arrNativeImages[i].height = images[i]->Height;
        }

        ...

        int result = pack(parrNativeImages[0], _nb_images, nativeParams);

        // Use OUT params from arrNativeImages[i]
        ...

        // Finally don't forget to delete the created array...
        delete[] arrNativeImages;
        arrNativeImages = NULL;
    }