Reputation: 115
I need to use my c++ code in c# application. I thought about pinvoke, but I'm confused with the approach I should take for creating dll from my c++ app.
Basically, my c++ app is a main
function, which runs an endless loop of data processing and I dont know how I can export such thing to dll and call it from c#.
I tried to rewrite my main
function in standalone init
function for dll and call it from c#, but because its a endless loop it never came to the point with return
from function. And I dont know how to get my data buffer from endless loop at some point to my c# app.
What I've done currently:
// 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);
I dont know how to call OpenRTSP from c#, because it will never return from this func and how to write a function, which will return me a data buffer from endless loop?
Upvotes: 1
Views: 465
Reputation: 9650
Since your C++ program runs a continuous process, you'd probably better leave it a standalone process and run it from your C# code using Process
class. The data from you C++ process can be passed by virtue of some IPC methods. The simple STDOUT seems to fit your task quite well. This post describes how it can be achieved.
Here's a brief code sample:
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();
If the buffer you send back from the C++ app should rather be binary, use BinaryReader
to read from the C++ app's STDOUT:
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...
}
Alternatively, you may change your main
function to a library function as you have already tried to do and pass it a callback function from C# as a parameters. But this would be more tedious and I personally would not go for this in your particular case.
Upvotes: 2
Reputation: 783
Create a CLR project and import it to c#, if you have the full c++ code it won't be a problem.
To do it just: New Project->C++->CLR->Class library. Then on the header you write something like this:
// 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
}
}
Then on the source file:
#include "stdafx.h"
#include "filename.h"
int YourNampespace::YourClass::__stdcall OpenRTSP(char url, char progname)
{
//Code here
}
I almost don't know any c++ and I'm not sure what do you mean by "endless loop of data processing"¨, but you could write the which data is "sent" to a stream, return it to the c# app and read it from there. No interprocess things (I think that would bring more problems)
Upvotes: 0
Reputation: 129
If the function you need is indeed main()
and you don't need to interact with your C# application you can run your executable as an external process. Look at the documentation of System.Diagnostics.Process
how to do that.
If this is not the right option for you then try to call your blocking function via P/Invoke from a separate thread.
Upvotes: 0