[英]How to Use C++/CLI Within C# Application
我試圖從我的C#應用程序(通過C ++ / CLI)調用我的C ++庫。 我按照這個問題的例子(針對我的具體應用)。 我的應用程序的設置是:
不幸的是,當我真正去訪問我的C#應用程序中的CLR包裝器對象時,我收到以下錯誤:
找不到類型或命名空間名稱'YourClass'(您是否缺少using指令或程序集引用?)
我是否錯誤地設置了項目,或者還有其他我應該研究的內容? (不幸的是,我不能出於專有原因發布代碼,但這是一個非常簡單的代碼,很容易遵循上面的例子。)
更新:
所以我完全按照Chris所說的去做(見下面的答案),但我仍然收到來自我的C#應用程序的消息“找不到類型或命名空間名稱'MyProgram'(你是否缺少using指令或程序集)參考?)。這是我的代碼的(模擬)。
MyWrapper.h
#pragma once
#include "myorigapp.h"
using namespace System;
namespace MyProgram
{
public ref class MyWrapper
{
private:
myorigapp* NativePtr;
public:
MyWrapper()
{
NativePtr = new myorigapp();
}
~MyWrapper()
{
delete NativePtr;
NativePtr = NULL;
}
void dostuff()
{
NativePtr->dostuff();
}
}
}
Program.cs中
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyProgram;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
MyWrapper p = new MyWrapper();
p.dostuff();
}
}
}
Project3引用引用Project1的Project2。 一切都沒有錯誤地構建(除了上面在using MyProgram
線的C#代碼中描述的錯誤)。
僅僅包含純C ++應用程序的頭文件就不夠好了。 您需要在Project2中使用托管對象包裝非托管對象(即public ref class YourClassDotNet
)
#include "YourHeader.h"
namespace MyManagedWrapper
{
public ref class YourClassDotNet
{
private:
YourClass* ptr;
public:
YourClassDotNet()
{
ptr = new YourClass();
}
~YourClassDotNet()
{
this->!YourClassDotNet();
}
!YourClassDotNet()
{
delete ptr;
ptr = NULL;
}
void SomeMethod()
{
ptr->SomeMethod();
}
}
}
好吧,我現在感到愚蠢。
事實證明我遇到的問題(幾周前我解決了 - 只是更新了這個答案)就是我已經包含了頭文件(請參閱Chris的答案),但我實際上沒有包括CPP文件(除了包含頭文件之外是空的)。
一旦我這樣做,DLL編譯正確,我可以從我的C#代碼調用C ++函數(使用C ++ / CLI)。
Chris向您展示了創建使用非托管代碼的托管類的方法。 你可以在C#中使用不安全的東西(很少有人這么做)。
但是,反過來也是可能的:直接從本機類型/函數使用.NET類型。
需要注意的是,任何托管指針都必須標記為這樣。 為此,C ++ / CLI定義了一種特殊類型的smartpointer gcroot<T>
(在某種程度上模仿boost :: shared_pointer或std :: auto_ptr)。 因此,要在C ++類中存儲托管字符串,請使用以下命令:
#include <string>
#include <vcclr.h>
using namespace System;
class CppClass {
public:
gcroot<String^> str; // can use str as if it were String^
CppClass(const std::string& text) : str(gcnew String(text.c_str())) {}
};
int main() {
CppClass c("hello");
c.str = gcnew String("bye");
Console::WriteLine( c.str ); // no cast required
}
請注意(如果這些天沒有修復),您將遇到托管null
和C / C ++ NULL之間不匹配的摩擦。 您無法像預期的那樣輕松打字:
gcroot<Object^> the_thing;
...
if (the_thing != nullptr)
...
}
相反,你必須使用本機樣式(智能包裝gcroot
處理這個)
gcroot< Object^ > the_thing;
if ( the_thing != NULL ) {} // or equivalently...
if ( the_thing ) {}
// not too sure anymore, but I thought the following is also possible:
if ( the_thing != gcroot<Object>(nullptr) ) {}
注意: 我在這些日子附近的任何地方都無法訪問Windows機器,因此我引用了內存
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.