我想将音频计算委托给C++层,但是通过WPF GUI处理和编辑音频内容.
我简要介绍了C++/CLI,我想知道:
编辑:随着火焰战可能开始.这是一个关于基准游戏的链接,它明确指出C/C++是速度获胜者.我在问:我应该在C++ Dll或C++ CLI程序集中编写C++.
我已经与C#广泛合作,但是,我正在开始一个项目,我们的客户希望所有代码都用C++而不是C#编写.该项目将是托管(.NET 4.0)和本机C++之间的混合.因为我总是更喜欢C#到C++以满足我的.NET需求,我想知道在使用C#和托管C++之间是否存在任何重要的差异?
我们非常感谢您对此的任何见解.
编辑查看维基百科的托管C++代码表明新规范是C++/CLI,并且不推荐使用"托管C++".更新了标题以反映这一点.
我对C++/CLI中的资源管理非常困惑.我认为我有一个句柄(没有任何双关语),但我偶然发现了整个auto_gcroot<T>课程,同时查看了头文件,导致谷歌搜索,然后是阅读文档的更好部分,现在混乱.所以我想我会转向社区.
我的问题涉及auto_handle/stack语义和auto_gcroot/gcroot之间的区别.
auto_handle:我的理解是这将清理托管函数中创建的托管对象.我的困惑是,垃圾收集者不应该为我们这样做吗?这不是托管代码的重点吗?更具体:
//Everything that follows is managed code
void WillThisLeak(void)
{
String ^str = gcnew String ^();
//Did I just leak memory? Or will GC clean this up? what if an exception is thrown?
}
void NotGoingToLeak(void)
{
String ^str = gcnew String^();
delete str;
//Guaranteed not to leak, but is this necessary?
}
void AlsoNotGoingToLeak(void)
{
auto_handle<String ^> str = gcnew String^();
//Also Guaranteed not to leak, but is this necessary?
}
void DidntEvenKnowICouldDoThisUntilToday(void)
{
String …Run Code Online (Sandbox Code Playgroud)我知道在C++/CLI中,在定义托管类时不能使用非托管类型:
public struct Unmanaged
{
int x;
int y;
};
public ref class Managed
{
int one;
Unmanaged two; //error C4368
};
Run Code Online (Sandbox Code Playgroud)
我不明白为什么.Unmanaged它只是一个本机类型的集合 - 它的大小是已知的,当然它(我的意思是定义它的内存块)将被Managed"托管堆"内部的" 内存块"移动,并且元数据中存储的任何偏移都将保持有效,不是吗?就像声明了整数或浮点数一样?
为什么我们不能混合类型?
在我正在使用的项目中,我遇到了一个新的链接器错误:
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.basic_string<char,std::char_traits<char>,std::allocator<char> >): (0x0200004e).
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >): (0x02000075).
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_iterator<char,std::char_traits<char>,std::allocator<char> >): (0x02000091).
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_const_iterator<char,std::char_traits<char>,std::allocator<char> >): (0x02000092).
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed …Run Code Online (Sandbox Code Playgroud) 我正在使用C++/CLI,使用MSDN文档和ECMA标准以及Visual C++ Express 2010.令我震惊的是以下与C++的不同之处:
对于ref类,必须编写终结器和析构函数,以便可以多次执行它们以及尚未完全构造的对象.
我编造了一个小例子:
#include <iostream>
ref struct Foo
{
Foo() { std::wcout << L"Foo()\n"; }
~Foo() { std::wcout << L"~Foo()\n"; this->!Foo(); }
!Foo() { std::wcout << L"!Foo()\n"; }
};
int main()
{
Foo ^ r;
{
Foo x;
r = %x;
} // #1
delete r; // #2
}
Run Code Online (Sandbox Code Playgroud)
在块的末尾#1,自动变量x死亡,并且析构函数被调用(它反过来调用终结器,就像通常的习惯用法一样).这一切都很好.但后来我通过引用再次删除了该对象r!输出是这样的:
Foo()
~Foo()
!Foo()
~Foo()
!Foo()
Run Code Online (Sandbox Code Playgroud)
问题:
delete r在线呼叫是不确定的行为,还是完全可以接受#2?
如果我们删除行#2,那么r对于一个(在C++意义上)不再存在的对象的跟踪句柄是否重要?这是一个"晃来晃去的手柄"吗?它的引用计数是否会导致尝试双重删除?
我知道没有实际的双删除,因为输出变为: …
我有一个WPF应用程序,可以在大型数据集中进行大量匹配,目前它使用C#和LINQ来匹配POCO并在网格中显示.随着所包含数据集的数量增加,数据量增加,我被要求查看性能问题.我今天晚上测试的一个假设是,如果我们将一些代码转换为C++ CLI,是否存在实质性差异.为此,我编写了一个简单的测试,创建了List<>5,000,000个项目,然后做了一些简单的匹配.基本对象结构是:
public class CsClassWithProps
{
public CsClassWithProps()
{
CreateDate = DateTime.Now;
}
public long Id { get; set; }
public string Name { get; set; }
public DateTime CreateDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我注意到的一件事是,平均而言,对于创建列表的简单测试,然后构建具有偶数ID的所有对象的子列表,C++/CLI代码在我的开发机器上慢了大约8%(64位Win8) ,8GB的RAM).例如,创建和过滤C#对象的情况需要大约7秒,而C++/CLI代码平均需要大约8秒.好奇,为什么这会是这样,我用ILDASM看看发生了什么在幕后发生的事情,并惊讶地看到,C++/CLI代码是在构造函数额外的步骤.首先是测试代码:
static void CreateCppObjectWithMembers()
{
List<CppClassWithMembers> results = new List<CppClassWithMembers>();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < Iterations; i++)
{
results.Add(new CppClassWithMembers() { Id = i, Name = string.Format("Name {0}", i) });
}
var halfResults = …Run Code Online (Sandbox Code Playgroud) 我正在使用动态库(.dll)和x64模式中的VS 2012开发C++/CLI项目.
如果我将模式切换到静态库,我会收到以下错误.
错误1错误C1107:找不到程序集'mscorlib.dll':请使用/ AI指定程序集搜索路径或通过设置LIBPATH环境变量C:\ Depot\Main\Current\Sln\ALibraryProject\Stdafx.cpp 1 1 ALibraryProject
我尝试删除对mscorlib.dll的引用,然后再从以下位置添加它:
项目>属性>常规>公共属性
但这没有帮助.我知道VS处理对.NET程序集的引用,我不想添加磁盘文件引用,因为它似乎不合逻辑!以前有人面对这个吗?
我是来自非托管C++世界的C++ CLI的新手.
我收到这个错误:
candidate function(s) not accessible
Run Code Online (Sandbox Code Playgroud)
当我传递一个std :: string作为方法参数的一部分.
这是确切的代码:
Lib Project(编译为.dll项目)
//Lib.h
#pragma once
public ref class Lib
{
public:
Lib(void);
public:
void Extract( std::string& data_ );
};
Run Code Online (Sandbox Code Playgroud)
//Lib.cpp
#include "Lib.h"
Lib::Lib(void)
{
}
void Lib::Extract( std::string& data_ )
{
data_.empty();
}
Run Code Online (Sandbox Code Playgroud)
LibTest项目(编译为application.exe)
// LibTest.h
#pragma once
ref class LibTest
{
public:
LibTest(void);
};
Run Code Online (Sandbox Code Playgroud)
// LibTest.cpp
#include "LibTest.h"
LibTest::LibTest(void)
{
Lib^ lib = gcnew Lib;
lib->Extract( std::string("test") );
}
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器错误:
1>------ Build …Run Code Online (Sandbox Code Playgroud)