c++ dll을 c#에서 사용 질문(c++/cli etc..)

필요한 작업

  • c++로 작성된 dll을 c#환경에서 사용하려함
  • .dll / .h / .lib 만 있고 프로젝트는 없음
  • 헤더파일에 std::vector가 사용되어있음

Q1) 위작업을 하기위해 찾아보니 std::vector가 c#에서 바로 맞춰쓸수가(마샬링) 없어서

  1. c++ dll을 c++/cli로 랩핑 -> c++/cli로 랩핑된 dll을 c#에서 불러서 사용
  2. 혹은 std::vector를 포기하고 int 배열 같은 고정 인덱스 배열로 변환해서 사용

의 과정을 거쳐야 한다고 하는 것 같습니다… 제대로 이해한것이 맞는지,
다른 적절한 방법이 있는지 궁금합니다.

Q2) c++/cli 랩핑과정들을 찾아보니 c++프로젝트의 참조가 필요한듯합니다…(맞나요?)
현재상황처럼 .dll / .h / .lib만 가지고있는 상태에서는 방법이 없을까요?

필요한 작업 을 해결하기 위한 좋은 접근방법이나 키워드가 있다면
조언 부탁드립니다.

감사합니다.

1 Like

C++로 lib파일을 만드시고요.
C++/cli로 아까만든 lib을 이용해서 dll로 만드세요.

근데 이 과정에서 managed c++문법을 좀 아셔야되요
검색하시면 나오긴하는데 흠…
나중에 시간되면 제가 올려드릴수있는지 확인해보겠습니다.

마지막으로 dll을 c#에서 사용하면됩니다.

1 Like
LibraNoirFilterManagerWrap::LibraNoirFilterManagerWrap() : _manager(new LibraNoir::LibraNoirFilterManager())
{

}

LibraNoirFilterManagerWrap::~LibraNoirFilterManagerWrap()
{
	if (_manager)
		delete _manager;
}

bool LibraNoirFilterManagerWrap::InstallProcessProctectionWrap()
{
	return _manager->InstallProcessProctection();
}

bool LibraNoirFilterManagerWrap::UnInstallProcessProtectionWrap()
{
	return _manager->UnInstallProcessProtection();
}

bool LibraNoirFilterManagerWrap::AddFileExtensionWrap(System::String^ fileExtension)
{
	return _manager->AddFileExtension(msclr::interop::marshal_as<std::wstring>(fileExtension));
}

bool LibraNoirFilterManagerWrap::RemoveFileExtensionWrap(System::String^ fileExtension)
{
	return _manager->RemoveFileExtension(msclr::interop::marshal_as<std::wstring>(fileExtension));
}

ref class MessageWrap^ LibraNoirFilterManagerWrap::WaitMessagWrap()
{
	LibraNoir::SEND_DATA data = _manager->WaitMessage();

	ref class MessageWrap^ msg = gcnew MessageWrap(data.Msg.ProcessId, data.Msg.FilePath, data.MessageHeader.MessageId);

	return msg;
}

bool LibraNoirFilterManagerWrap::ReplyMessageWrap(unsigned long long msgId, bool permit)
{
	return _manager->ReplyMessage(msgId, permit);
}

bool LibraNoirFilterManagerWrap::isConnectedWrap()
{
	return _manager->isConnected();
}

MessageWrap::MessageWrap(unsigned long pid, wchar_t* filepath, unsigned long long msgId) : _pid(pid), _filepath(gcnew System::String(filepath)), _msgId(msgId)
{

}

MessageWrap::~MessageWrap()
{

}

이게 제가 그런 용도로 만든 랩퍼 dll인데요.

ref class MessageWrap^ LibraNoirFilterManagerWrap::WaitMessagWrap()
{
	LibraNoir::SEND_DATA data = _manager->WaitMessage();

	ref class MessageWrap^ msg = gcnew MessageWrap(data.Msg.ProcessId, data.Msg.FilePath, data.MessageHeader.MessageId);

	return msg;
}

약간 이런 managed c++ 문법을 써서 해야됩니다.

간단하게 말해드리면 ref class는 c#의 클래스와 같은거구요. ^로 된 변수는 가비지컬렉터가 관리하는 겁니다.

https://docs.microsoft.com/ko-kr/cpp/extensions/handle-to-object-operator-hat-cpp-component-extensions?view=vs-2019

https://docs.microsoft.com/ko-kr/cpp/cppcx/ref-classes-and-structs-c-cx?view=vs-2019

참고하세요.

  1. vector안에 데이터를 c#의 자료구조형에 옮기면될겁니다.
  2. 아마 프로젝트는 필요했던거 같아요.
1 Like

감사합니다 ㅜㅜ 도움주신부분으로 더 찾아보고 츄라이 해보겟습니다. 프로젝트가 없으면 랩핑이 안된다면 cli랩핑으로 지금 문제를 해결할 수는 없을지 모르겠지만… 그래도 알아두고 쓰고싶은 내용이라 큰 도움 될것같습니다ㅎㅎ 어떻게 길이좀 풀리는것 같네요ㅎ

lib파일과 헤더가 있으면 아마 가능할거 같습니다.
링킹만 되면 되겠죠… 아마
저도 확신할 순 없지만… ㅠㅠ

저도 managed c++ 공부를 더 해봐야겠네요 ㅎㅎㅎ
항상 미뤄만 와서 ㅋㅋㅋ