标签: c++-cli

使用托管C++/CLI中的C#扩展方法

如果我的术语有点偏离,请原谅我.我对托管C++/CLI的了解非常有限.

我有一个MFC应用程序使用启用了/ clr选项的DLL.这个dll使用几个C#dll与使用WCF的服务器通信.在大多数情况下,这工作正常.

在C#的DLL中的一个,我已经添加扩展方法的System.Net.IPAddress类,将检索的对象的IPAddress子网掩码(使用UnicastIPAddressInformation类及其IPv4Mask).扩展方法在C#方面运行良好,但我无法弄清楚如何在托管C++/CLI代码中使用它.

首先,这甚至可能吗?如果是这样,托管C++/CLI端的语法是什么样的?我必须使用/ clr:pure选项才能使用吗?

以下是扩展方法的示例:

using System.Net;
using System.Net.NetworkInformation;
public static class IPAddressExtensions
{
    public static IPAddress GetSubnetMask(this IPAddress address)
    {
        UnicastIPAddressInformation addressInfo = address.GetAddressInformation(); // elided
        return ((addressInfo != null) ? addressInfo.IPv4Mask : null);
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的托管C++代码中,如果可能的话,我将如何使用此扩展方法?

unsigned long bytes= 0x010000FF; // example address - 127.0.0.1
IPAddress^ address = gcnew IPAddress(BitConverter::GetBytes(bytes));
IPAddress^ subnet = address->GetSubnetMask(); // how do I do this???
Run Code Online (Sandbox Code Playgroud)

.net c# unmanaged c++-cli .net-3.5

10
推荐指数
1
解决办法
4787
查看次数

如何在Release()上处理NET COM互操作对象

我有一个用托管代码(C++/CLI)编写的COM对象.我在标准C++中使用该对象.
当COM对象被释放时,如何强制立即调用COM对象的析构函数?如果那是不可能的,请调用我有Release()调用我的COM对象上的MyDispose()方法?

我的代码声明对象(C++/CLI):

    [Guid("57ED5388-blahblah")]
    [InterfaceType(ComInterfaceType::InterfaceIsIDispatch)]
    [ComVisible(true)]
    public interface class IFoo
    {
        void Doit();
    };

    [Guid("417E5293-blahblah")]
    [ClassInterface(ClassInterfaceType::None)]
    [ComVisible(true)]
    public ref class Foo : IFoo
    {
    public:
        void MyDispose();
        ~Foo() {MyDispose();} // This is never called
        !Foo() {MyDispose();} // This is called by the garbage collector.
        virtual ULONG Release() {MyDispose();} // This is never called
        virtual void Doit();
    };

我使用该对象的代码(本机C++):

#import "..\\Debug\\Foo.tlb"
...
Bar::IFoo setup(__uuidof(Bar::Foo)); // This object comes from the .tlb.
setup.Doit();
setup->Release(); // explicit release, not really necessary since …

.net com interop release c++-cli

10
推荐指数
2
解决办法
1万
查看次数

如何将C#和C++程序集链接到单个可执行文件中?

我有VS2008解决方案包含一个项目,该项目生成一个C#可执行文件,该项目引用了一个生成包含C++/CLI和非托管C++的DLL的项目.

我想将这些合并到一个可执行文件中,因为C++ DLL包含我想要嵌入主可执行文件的安全代码.

我不能使用ILMerge,因为dll包含托管代码和非托管代码.建议的解决方案似乎是使用link.exe将C#程序集与C++目标文件链接起来.这就是我想要做的.

我手动编辑了c#可执行文件的项目文件以生成netmodule.我在可执行项目中添加了一个构建后步骤,以运行link.exe将c#netmodule和已编译的C++目标文件链接在一起,然后运行mt.exe来合并两个项目创建的程序集清单.这运行成功,但是exe仍然包含对C++项目的正常构建过程生成的dll中定义的c ++类型的引用和使用.

然后我在C++ dll的项目设置中指定了/ NOASSEMBLY,因此它还生成了一个netmodule.在C#项目中,我删除了对C++项目的引用,但在解决方案中添加了项目依赖性.我手动编辑了C#项目文件,包括类似于:

<ItemGroup>
    <AddModules Include="..\Debug\librarycode.netmodule" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

即引用现在由C++项目生成的C++ netmodule.

但是,现在我的post build事件中的链接器步骤失败了:

error LNK2027: unresolved module reference 'librarycode.netmodule'
fatal error LNK1311: 1 unresolved module references: 
Run Code Online (Sandbox Code Playgroud)

这完全可以理解,因为我没有链接到librarycode netmodule; 我链接在用于生成netmodule的C++目标文件中.

简而言之,如何将ac#executable和C++目标文件合并到一个程序集中?我错过了什么?

到目前为止我的引用源(来自MSDN上的link.exe命令链接引用等)是以下两篇文章:

非常感谢你提前.


UPDATE1

我在Steve Teixeira的博客中完全遵循了这个例子,并证实它有效.使用反射器,我可以看到生成的可执行文件包含两个netmodule.c#netmodule包含对另一个netmodule的引用但没有名称?!如果将程序集移动到新目录,则第二个netmodule变为未引用(显然),但可执行文件仍然运行,因为c#netmodule中存在具有正确定义的类型.

请注意,原始c#netmodule确实包含对c ++ netmodule的命名引用,因此它必须是删除名称的链接器步骤.

试图在我的示例项目中遵循此示例,我已将/ ASSEMBLYMODULE参数添加到我的后期构建链接器步骤中.链接器现在失败了

LNK2022: metadata operation failed (80040427) : Public type 'MixedLanguageLibrary.Class1' is defined in multiple places in this assembly: 'MixedLanguageDemo.exe' and 'mixedlanguagelibrary.netmodule'
LINK : fatal error LNK1255: link failed because of metadata errors
Run Code Online (Sandbox Code Playgroud)

我猜这是链接器魔术删除我缺少的模块引用名称. …

c# linker c++-cli visual-c++

10
推荐指数
1
解决办法
6806
查看次数

如何在.NET中执行/打开任何文件

如果我有任何类型的文件路径(.doc,.pdf,.png ...等),我想打开该文件,因为它是通过双击打开(无需确定主机程序).我的意思是:.doc文件需要通过MS Word或机器中存在的任何文字处理器打开,并设置为defualt文字处理器.

.net c# c++-cli

10
推荐指数
2
解决办法
1万
查看次数

C++/CLI中的值类

在C++/CLI中使用值类有什么好处.值类包含成员函数吗?

c++ c++-cli managed

10
推荐指数
1
解决办法
6344
查看次数

Visual Studio 2012 winform设计师非常慢

我们最近将一个Winforms项目从Visual Studio 2008迁移到了Visual Studio 2012.转换过程非常顺利,所有内容都很好,但我们现在正在努力与winforms设计器一起运行,它的运行速度非常慢.

举个例子,如果我们打开一个小表单(表单包含两个文本框,一个数字更新和两个按钮 - 所有标准内置控件,没有第三方),2012年大约需要40-45秒在2008年,它会在1或2秒内打开.对于我们较大的形式,这种差异更加明显.在2008年,打开表格需要大约7秒钟,但在2012年需要6分钟.最糟糕的是,这是一个阻塞动作,VS2012在打开表单时几乎完全没有响应.这也是通过单击表单的.h来实现的,所以我们不能仅仅通过坚持代码本身来轻松避免它.

还有其他人经历过这个吗?有谁知道它为什么会发生,如果有什么可以做的吗?

其他信息:我们的应用程序是一个C++/CLI winforms应用程序.在我们所有运行Windows 7 x64的开发机器上都可以看到这种行为.我的机器是Core i7 860 CPU,内存为12Gb(现在我正在对以上内容进行基准测试时超过60%) - 绰绰有余,我想.在任何情况下,我的系统运行速度都不慢,它只是VS2012的设计者.

编辑:只是为了进一步澄清,我们没有安装任何插件或类似的东西.这是一个处女VS2012安装.

EDIT2:它似乎也不是网络的东西.

.net c++-cli windows-forms-designer winforms visual-studio-2012

10
推荐指数
1
解决办法
4897
查看次数

防止在非托管代码中使用的托管引用的垃圾回收

我的C#应用​​程序使用包装的C++代码进行计算.

C++标题:

__declspec(dllexport) void SetVolume(BYTE* data, unsigned int width);
Run Code Online (Sandbox Code Playgroud)

C++/CLI包装器:

void SetVolume(array<Byte>^ data, UInt32 width) 
{
    cli::pin_ptr<BYTE> pdata = &data[0];
    pal->SetVolume(pdata, width); 
}
Run Code Online (Sandbox Code Playgroud)

C# :

public startCalc()
{
    byte[] voxelArr = File.ReadAllBytes("Filtered.rec");
    palw.SetVolume(voxelArr, 490);
    //GC.KeepAlive(voxelArr); makes no sense
}
Run Code Online (Sandbox Code Playgroud)

C++ SetVolume函数启动异步计算.voxelArr不再从受管方引用,并且是垃圾回收.

在非托管代码完成它的工作而不声明voxelArr为全局变量之前,如何防止此引用的垃圾收集?创建数组副本不是一个选项,因为实际上有很多数据.内部的积极等待startCalc()也不好.

c# garbage-collection c++-cli wrapper

10
推荐指数
1
解决办法
3451
查看次数

生成.dll的初始化代码

我最近听说.dd一旦加载就可以运行代码,例如,当加载引用.dll的应用程序时.事件虽然我做了一些我自己的测试,并尝试在这里寻找答案,在谷歌我无法找到一些方法来生成.dll的初始化方法.

我想知道是否真的可以在应用程序加载时从.dll运行代码.

如果是这样,我该怎么办?

c# c++-cli

10
推荐指数
1
解决办法
7273
查看次数

为什么不保护C++ - Cli析构函数会导致编译错误?

如果我编译并运行以下代码:

using namespace System;

ref class C1
{
public:
    C1()
    {
        Console::WriteLine(L"Creating C1");
    }

protected:
    ~C1()
    {
        Console::WriteLine(L"Destroying C1");
    }
};

int main(array<System::String ^> ^args)
{

    C1^ c1 = gcnew C1();
    delete c1;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

...代码编译没有错误,并运行给我这个:

Creating C1
Destroying C1
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

如果我在C++中执行相同操作,则会出现以下错误:

1>ProtectedDestructor.cpp(45): error C2248: 'C1::~C1' : cannot access protected member declared in class 'C1'
1>          ProtectedDestructor.cpp(35) : compiler has generated 'C1::~C1' here
1>          ProtectedDestructor.cpp(23) : see declaration of 'C1'
Run Code Online (Sandbox Code Playgroud)

...那么为什么它在CLI中有效?

destructor c++-cli

10
推荐指数
2
解决办法
393
查看次数

在没有Pdb文件的Visual Studio中进行调试(C++ Access Voilation)

我使用Cmake和visual studio构建了OpenCV二进制文件(.dll),它生成了.pdb文件,帮助我在代码中找到问题(部分!)

这次崩溃是如何造成的..
我正在使用一种软件,我们可以为任何特定程序设置互联网下载速度限制(传输速率).

现在,如果我将IP摄像头连接到下面的代码,我注意到我的应用程序需要大约100Kb/s的互联网使用率(传输速率) - 只有这样我才能无缝地观看直播.让我说我减少(设置)我的应用程序互联网使用量为10Kb/s [这是崩溃背后的原因] 在这种情况下,我应该能够在4秒内看到一个新的框架.

我收到访问冲突错误可能是因为(cap>>img;)上限试图到达ram中的位置并获取帧但是没有帧YET因为它仍然因为低网速而被下载.
很明显,指针到达ram中的某个位置以抓住尚未存在的帧.

一些有趣的行为...

Void OpenCamera()
{
    VideoCapture cap("http://192.168.1.3:8080/video?x.xmjpeg");
    Mat img;
    while(true)
    {
      try
      {
        if(cap.isOpened()) //also tried grab + retrieve, crashes at grab
        cap>>img; //code crashes here
      }
      catch(...)
      {
        cout<<"Camera Disconnected"<<endl;
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我在同一个类中使用整个代码(在相同的头文件中),根本没有问题(新帧在4秒以上显示而不会使程序崩溃)但是如果我将代码放入一个单独的类(不同的头文件) ),然后调用该函数从类对象打开相机,然后如果减少 互联网速度它崩溃.
奇怪的行为 - 如果我一步一步调试,它永远不会崩溃!

当我使用ffmpeg构建opencv库时,我只获取opencv(opencv_world310.pdb)的.pdb文件 - 所以没有问题调试使用调用堆栈,但我没有得到fdb for ffmpeg(因为Opencv_ffmpeg.dll是预编译的,这是它崩溃的地方)

因此很难调试,构建ffmpeg不会产生pdb文件,因为它使用MSYS构建,
所以可以用我们的调试吗?

我包括来自visual studio调试的快照,一些有助于理解的变量:

typedef int (*CvGrabFrame_Plugin)( void* capture_handle );      [cap_ffmpeg_api.cpp]
protected: void* ffmpegCapture;                                 [cap_ffmpeg.cpp]
static CvGrabFrame_Plugin icvGrabFrame_FFMPEG_p = …
Run Code Online (Sandbox Code Playgroud)

c++ opencv memory-management c++-cli visual-c++

10
推荐指数
1
解决办法
589
查看次数