2016-08-03 2 views
0

C# 응용 프로그램에서 C++ 코드를 사용해야합니다. pinvoke에 대해 생각했지만 C++ 응용 프로그램에서 DLL을 작성하기 위해 취해야하는 접근법과 혼동합니다. 기본적으로 내 C++ 응용 프로그램은 데이터 처리의 끝없는 반복을 실행하는 main 함수이며 나는 dll에 그런 것을 내보내고 C#에서 호출하는 방법을 알지 못합니다.main 함수에서 dll (C++) 함수를 사용하여 C에서 사용하는 방법 #

나는 DLL의 독립 init 기능에 내 main 기능을 재 작성 및 C#에서 호출하려고했으나 그 때문에 무한 루프가 함수에서 return과 지점에 온 적이. 그리고 내 데이터 버퍼를 끝내는 루프에서 어떤 지점에서 내 C# 응용 프로그램으로 가져 오는 방법을 모릅니다.

저는 현재 한 적이 무엇 :

내가이 FUNC에서 반환하지 않습니다 나에게 데이터 버퍼를 반환하는 함수를 작성하는 방법 때문에, C#을에서 OpenRTSP를 호출하는 방법을 잘 모릅니다
// myDLL.cpp 
int __stdcall OpenRTSP(char url, char progname) 
{ 
    TaskScheduler* scheduler = BasicTaskScheduler::createNew(); 
    UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); 

    if (openURL(*env, &progname, &url) < 0) 
    { 
     return -1; 
    } 

    // All subsequent activity takes place within the event loop: 
    // This function call does not return, unless programm closes. 
    env->taskScheduler().doEventLoop(&eventLoopWatchVariable); 

    return 0; 
} 

// myDLL.h 
__declspec(dllexport) int __stdcall OpenRTSP(char url, char progname); 

무한 루프에서?

답변

1

C++ 프로그램은 연속 프로세스를 실행하므로 독립 실행 형 프로세스로두고 Process class을 사용하여 C# 코드에서 실행하는 것이 좋습니다. C++ 프로세스의 데이터는 일부 IPC 방법으로 전달 될 수 있습니다. 간단한 STDOUT은 당신의 임무를 아주 잘 맞는 것처럼 보입니다. This post은 어떻게 달성 할 수 있는지 설명합니다.

var cppProcess = new Process(); 
cppProcess.StartInfo = new ProcessStartInfo 
{ 
    FileName = "YourCppApp.exe", 
    UseShellExecute = false, 
    RedirectStandardOutput = true, 
}; 
cppProcess.OutputDataReceived += (sender, arg) => 
{ 
    Console.WriteLine("Received: {0}", arg.Data); 
}; 
cppProcess.Start(); 
cppProcess.BeginOutputReadLine(); 

당신이 C++ 응용 프로그램에서 다시 전송 버퍼가 아니라 이진해야하는 경우, C++ 응용 프로그램의 STDOUT에서 읽을 BinaryReader를 사용 :

var cppProcess = new Process(); 
cppProcess.StartInfo = new ProcessStartInfo 
{ 
    FileName = "YourCppApp.exe", 
    UseShellExecute = false, 
    RedirectStandardOutput = true, 
}; 
cppProcess.Start(); 
using (var cppOutput = new BinaryReader(cppProcess.StandardOutput.BaseStream)) 
    while (!cppProcess.StandardOutput.EndOfStream) 
    { 
     var buffer = new byte[4096]; 
     int bytesRead= cppOutput.Read(buffer, 0, buffer.Length); 
     // Process the buffer... 
    } 

여기에 간단한 코드 예제입니다

또는 main 함수를 이미 라이브러리 함수로 변경하고 C#의 콜백 함수를 매개 변수로 전달할 수 있습니다. 그러나 이것은 더 지루하고 개인적으로 당신의 특별한 경우에 이것을 위해 가지 않을 것입니다.

+0

몇 가지 작업을 한 후에 독립 실행 형 프로세스가'dllimport' 방법보다 훨씬 빠르다는 것을 알게되었습니다. 도와 주셔서 감사합니다. 또한, 다른 사람들을위한 것들을 명확히하기 위해서 - 나는 C++과 C# 사이의 파이프 데이터 전송으로 그것을 테스트했다. – Aleksey

0

필요한 기능이 실제로 main()이고 C# 응용 프로그램과 상호 작용할 필요가없는 경우 실행 파일을 외부 프로세스로 실행할 수 있습니다. System.Diagnostics.Process 설명서를 참조하십시오.

이것이 올바른 옵션이 아니면 P/Invoke를 통해 별도의 스레드에서 차단 기능을 호출 해보십시오.

0

전체 C++ 코드가있는 경우 CLR 프로젝트를 만들어 C#으로 가져 오면 문제가되지 않습니다.

새로운 프로젝트 -> C++ -> CLR -> 클래스 라이브러리.

// filename.h 
#pragma once 

using namespace System; 

namespace YourNampespace 
{ 
    public ref class YourClass abstract sealed 
    { 
    //int __stdcall OpenRTSP(char url, char progname); 
    //You want to convert this to managed, buf if you return "int", with "char" params, 
    // it won't be a problem 
    } 
} 

그런 다음 소스 파일에 : 그런 다음 머리글은 다음처럼 작성할 수

#include "stdafx.h" 
#include "filename.h" 
int YourNampespace::YourClass::__stdcall OpenRTSP(char url, char progname) 
{ 
//Code here 
} 

나는 거의 모든 C++를 모르는 당신이로 뜻 모르겠어요 "무한 루프의 데이터 처리"¨,하지만 당신은 어떤 데이터가 스트림으로 보내 졌는지 쓸 수 있고, 그것을 C# app으로 돌려 보내서 거기에서 읽을 수 있습니다.프로세스 간 일이 없음 (더 많은 문제를 야기 할 것임)

관련 문제