2016-08-03 13 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は、その達成方法を記載しています。あなたが戻ってC++アプリから送信バッファではなくバイナリである必要がある場合はC++アプリのSTDOUTからの読み取りにBinaryReaderを使用し、

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(); 

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

CLRプロジェクトを作成してc#にインポートします。完全な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#のアプリに戻し、そこからそれを読んでください。プロセス間の関係がない(より多くの問題を引き起こすと思います)

関連する問題