我在本机C++类中使用boost :: signal,现在我在C++/CLI中编写.NET包装器,这样我就可以将本机C++回调公开为.NET事件.当我尝试使用boost :: bind来获取托管类的成员函数的地址时,我得到编译器错误3374,说我不能获取成员函数的地址,除非我创建一个委托实例.有谁知道如何使用boost :: bind绑定托管类的成员函数?
为了澄清,以下示例代码导致编译器错误3374:
#include <boost/bind.hpp>
public ref class Managed
{
public:
Managed()
{
boost::bind(&Managed::OnSomeEvent, this);
}
void OnSomeEvent(void)
{
}
};
Run Code Online (Sandbox Code Playgroud) 我在解决方案中有两个项目,一个是C#库,另一个是C++/CLI库.
我在C++/CLI项目中使用引用菜单添加了一个引用到c#库.然后我添加了
#using <assembly.name.dll>
Run Code Online (Sandbox Code Playgroud)
并尝试引用程序集
using namespace namspace.subnamespace;
Run Code Online (Sandbox Code Playgroud)
但我得到无法找到assembly.name.dll的错误.我已经尝试将案例和所有小写字母匹配为程序集名称,但无济于事.令人惊讶的是,互联网上没有任何关于如何引用自己创建的程序集的参考.
这样做是正确的,如果我做得对,我应该采取什么方法来诊断这一点.
我使用.NET DateTime来获取当前日期和时间.我正在将其转换为字符串,以用作文件名的一部分.问题是保存图像的OpenCV命令需要char*而不是字符串类型,而DateTime只输出String ^类型.我该如何工作?继承人未完成的代码
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
IplImage* toSave;
CvCapture* capture = cvCreateCameraCapture(0);
toSave = cvQueryFrame( capture );
cvSaveImage(nowString, toSave);
cvReleaseImage(&toSave);
cvReleaseCapture(&capture);
Run Code Online (Sandbox Code Playgroud) 是否可以将Visual C++ 2010中的新lambda表达式用作CLR事件处理程序?我试过以下代码:
SomeEvent += gcnew EventHandler(
[] (Object^ sender, EventArgs^ e) {
// code here
}
);
Run Code Online (Sandbox Code Playgroud)
它会导致以下错误消息:
错误C3364:'System :: EventHandler':委托构造函数的参数无效; 委托目标需要是指向成员函数的指针
我是在尝试不可能的,还是仅仅是我的语法错误?
如果您必须在C#和托管C++之间做出决定,您会选择哪个以及为什么?
托管C++相对于C#有什么好处?你更喜欢哪种语言?在什么情况下你会做出什么决定?
我使用Visual Studio 2010的单元测试框架遇到了一些问题.目前,QTAgent32将在测试执行完成后维护对DLL的引用.
有问题的DLL是围绕一些本机c ++代码的c ++/cli包装器.包装器公开的对象实际上从未由托管代码分配.它唯一的参考是在处理过程中进行最后检查,以确定它是否在课程的生命周期中设置.
If(_obj != null)
{
_obj.Dispose();
_obj = null;
}
Run Code Online (Sandbox Code Playgroud)
我知道这是事实,因为如果我单步执行代码并观察调试器控制台输出,我可以看到DLL的符号没有加载,直到命中if(这是有意义的).涉及的所有托管对象都实现了IDisposable,以确保所有本机对象都得到谨慎以避免内存泄漏.
基于这个问题:QTAgent32保持文件打开 我确保没有显式打开文件流(包括控制台),甚至没有使用任何文件但问题仍然存在.关于该怎么做,我的想法已经不多了.
有人可以帮忙吗?
TL; DR: QTAgent32.exe保持对从未实例化的c ++/cli包装器的开放引用.
我正在一个大型非托管C++库和一个大型C#库上开发一个瘦托管C++包装器.我需要捕获源自该大型非托管C++库的错误,并将它们重新抛出为Clr异常.非托管库抛出以下类的实例:
Error::Error(const std::string& file, long line,
const std::string& function,
const std::string& message) {
message_ = boost::shared_ptr<std::string>(new std::string(
format(file, line, function, message)));
}
const char* Error::what() const throw () {
return message_->c_str();
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经想出了这个:
try{
// invoke some unmanaged code
}
catch(Object*)
{
throw gcnew System::Exception("something bad happened");
}
Run Code Online (Sandbox Code Playgroud)
如何从Error类中提取消息并将其转换为Clr String类,以便我可以将它传递给gcnew System :: Exception()构造函数?如果非托管代码抛出其他内容,我的catch块会抓住它吗?
编辑:我正在使用catch(Object*),因为在MCDN中建议使用它
我在Visual Studio 2012中有C#的代码.
public Task SwitchLaserAsync(bool on)
{
return Task.Run(new Action(() => SwitchLaser(on)));
}
Run Code Online (Sandbox Code Playgroud)
这将执行SwitchLaser方法(类的公共非静态成员MyClass)作为参数bool on的任务.
我想在托管C++/CLI中做类似的事情.但我无法找到如何运行任务的任何方法,该任务将执行采用一个参数的成员方法.
目前的解决方案是这样的:
Task^ MyClass::SwitchLaserAsync( bool on )
{
laserOn = on; //member bool
return Task::Run(gcnew Action(this, &MyClass::SwitchLaserHelper));
}
Run Code Online (Sandbox Code Playgroud)
执行SwitchLaserHelper功能:
void MyClass::SwitchLaserHelper()
{
SwitchLaser(laserOn);
}
Run Code Online (Sandbox Code Playgroud)
必须有一些像C#中的解决方案而不是创建辅助函数和成员(这不是线程安全的).
我的C++ MFC代码中有一个HWND,我想将这个HWND传递给C#控件并将其作为IntPtr.
我的代码有什么问题,我该怎么做才能正确?(我认为这是使用CLI指针的错误,因为我得到一个错误,它无法从System :: IntPtr ^转换为System :: IntPtr.但我不知道如何让它完全正常工作. ..)
我的C++ MFC代码:
HWND myHandle= this->GetSafeHwnd();
m_CLIDialog->UpdateHandle(myHandle);
Run Code Online (Sandbox Code Playgroud)
我的C#代码:
public void UpdateHandle(IntPtr mHandle)
{
......
}
Run Code Online (Sandbox Code Playgroud)
我的CLI代码:
void CLIDialog::UpdateHandle(HWND hWnd)
{
System::IntPtr^ managedhWnd = gcnew System::IntPtr();
HWND phWnd; // object on the native heap
try
{
phWnd = (HWND)managedhWnd->ToPointer();
*phWnd = *hWnd; //Deep-Copy the Native input object to Managed wrapper.
m_pManagedData->CSharpControl->UpdateHandle(managedhWnd);
}
Run Code Online (Sandbox Code Playgroud)
当前发生错误(无法从IntPtr ^转换为IntPtr) m_pManagedData->CSharpControl->UpdateHandle(managedhWnd);
如果我将CLI代码更改为:
void CLIDialog::UpdateHandle(HWND hWnd)
{
System::IntPtr managedhWnd;
HWND phWnd; // object on the native heap
try
{
phWnd …Run Code Online (Sandbox Code Playgroud) 我有一个复杂的C++/CLI应用程序,有许多模块(几十个),有些管理一些不受管理的模块.最近我们从Visual Studio 2013切换到Visual Studio 2015.它在某些计算机上运行,但在其他计算机上运行.
当程序不工作时,它甚至在主要的第一行之前崩溃.它报告了一个访问冲突异常_onexit.当忽略一些异常和断言时,我看到<Module>扔了一个TypeInitializationException.
问题是 - 我不知道哪一个.我可以看到在输出窗口中加载DLL的时间.最后加载的DLL是System.dll- 当然我的bug不存在.因此,我需要一种方法来跟踪托管DLL中的静态变量初始化,以便我可以找出哪个DLL存在问题,然后我可以跟踪有问题的初始化.
我怎样才能做到这一点?