如何从c#中使用的主函数中生成dll(c++)的函数
How to make function for dll (c++) from main function to use in c#
我需要在c#应用程序中使用我的c++代码。我想过pinvoke,但我对从我的c++应用程序创建dll的方法感到困惑。基本上,我的c++应用程序是一个main
函数,它运行着一个无休止的数据处理循环,我不知道如何将这样的东西导出到dll并从c#调用它。
我试图在dll的独立init
函数中重写我的main
函数,并从c#调用它,但因为这是一个无休止的循环,所以它从未达到使用return
from函数的目的。我不知道如何在某个时刻将我的数据缓冲区从无休止的循环中获取到我的c#应用程序。
我目前所做的:
// 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);
我不知道如何从c#调用OpenRTSP,因为它永远不会从这个函数返回,以及如何编写一个函数,它会从无尽的循环中返回一个数据缓冲区?
由于您的C++程序运行一个连续的进程,您可能最好将其保留为一个独立的进程,并使用Process
类从C#代码中运行它。C++进程中的数据可以通过一些IPC方法传递。简单的STDOUT似乎非常适合您的任务。这篇文章描述了如何实现这一目标。
下面是一个简短的代码示例:
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++应用程序发回的缓冲区应该是二进制的,请使用BinaryReader
从C++应用的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...
}
或者,您可以将main
函数更改为库函数,就像您已经尝试过的那样,并将C#中的回调函数作为参数传递给它。但这会更乏味,我个人不会在你的特殊情况下这样做。
如果您需要的函数确实是main()
,并且您不需要与C#应用程序交互,那么您可以将可执行文件作为外部进程运行。查看System.Diagnostics.Process
的文档中如何做到这一点。
如果这不是适合您的选项,请尝试从单独的线程通过p/Invoke调用您的阻塞函数。
创建一个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#应用程序,然后从那里读取。没有进程间的事情(我认为这会带来更多问题)
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- Visual c ++,使用字符串引用/指针调用 dll 函数
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- C++ DLL 引用C++.exe中的函数和类
- 如何使用导出的函数交叉编译 DLL
- 如何在窗口中使用注入的 dll 中的参数调用函数
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- 加载由 MATLAB Coder 生成的带有函数的 DLL,该函数调用外部函数
- PowerShell 使用结构类型参数调用 C++ DLL 的导出函数
- 从DLL导出函数,LoadLibrary()需要用TEXT转换的字符串才能编译而不会出错
- 从 C#-DLL 调用函数的 C++ 失败
- 如何在 DLL 内的成员函数中使用互斥/关键节
- 调用 "project" 函数和调用 DLL 函数之间的区别
- 函数指针分配在创建 DLL 后导致错误
- 从动态加载的 dll 内部调用C++函数
- 函数声明中的 WINAPI 标识符C++ DLL 入口点函数中的标识符
- LNK2019某些类函数,但不在其他类函数(DLL 中的模板类)上
- 从库导入函数./ DLL 文件
- 从 ntdll 调用 Nt 函数.dll在 Win32 环境中,C++
- 如何使用ctypes将python列表传递给C函数(dll)