如何从C#调用C 代码及其调用的代码
How to call C++ code, and the code it calls, from C#
tl; dr
我有旧版C 代码可以做东西(有时会返回内容(,调用其他CPP代码,但不是完整的类/obj。这个代码我无法更改。我正在制作新的C#代码,我希望从中调用C 代码。我不明白是创建称为原始旧版C 的DLL,还是创建CLR?这也称为传统CPP。在下面,我拥有已实施的示例代码(有问题(。
MAIN
我有传统和遗产。
这不是类/对象,仅具有公共功能,值和#Defines。lagacy.cpp和.h均#include其他文件和CPP库可以完成工作。
我有一个新项目,可以添加C#,C 代码
我很难理解我需要做的/研究,以调用legacy.cpp(或从我的新C#代码中的值/定义(中定义的任何功能。
我看过的一些包括
-
托管CLR包装器
- https://drthitirat.wordpress.com/2013/06/03/use-c-codes-in-codes-in-c-project-wrapping-native-native-c-with-a-a-man-maned-clr-wrapper/
- https://web.archive.org/web/20140806022309/http://blogs.msdn.com/b/borisj/archive/2006/09/28/28/769708.aspx
- 如何在C# 中调用C DLL
clr
我目前已经尝试创建一个CLR(以为我觉得这不是我在这种情况下需要的(,但是我在clr_wrapper.cpp中遇到了问题,它找不到对foo((
//Wrapper.cpp
#include "Wrapper.h"
#include "abspathtolegacycodelegacy.h"
#include "abspathtolegacycodelegacy.cpp"
int foo_Wrapper()
{
return foo(); //int foo() is declared in legacy.h and defined in legacy.cpp
}
#pragma once
#include "abspathtolegacycodelegacy.h"
#include "abspathtolegacycodelegacy.cpp"
using namespace System; //What things use this?
//Can I just prepend System:: to whatever needs it?
namespace Wrapper {
public ref class Wrapper
{
public:
int foo_Wrapper();
};
}
foo_wrapper((无法调用foo((。
我对此方法的困惑是,它看起来需要使CLR包装器成为具有成员函数的对象类,这些函数将根据需要调用。导致obj.foo()
的语法。如果我选择做某种CLR包装器,这需要做什么?
dll
我还考虑使所有dll都喜欢(如何在C#中调用C DLL(
但是,我对设置这个问题感到困惑。我目前的想法是让CPP DLL调用原始CPP(即创建Legacydll.dll,它将调用FOO((,然后我的主C#将调用__declspec(dllexport(函数,在extern" c" {}
当前设置(从"如何在c尖锐中调用c dll"(dllmain.cpp
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <iostream>
#include <Windows.h>
using namespace std;
extern "C"
{
__declspec(dllexport) void bar_Dll()
{
cout << "calling bar() in legacy code" << endl;
}
__declspec(dllexport) int foo_Dll()
{
cout << "calling foo() in legacy code" << endl;
//realistically I would have,
//return foo()
}
}
class1.cs
using System;
using System.Runtime.InteropServices;
namespace Test_DLL_Calling
{
class Class1
{
[DllImport("dllmain.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void bar_Dll();
[DllImport("dllmain.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int foo_Dll();
public static void Main(string[] arg)
{
bar_Dll(); //The specified module could not be found (Exception)
Console.WriteLine(foo_Dll()); //Im guessing this will also ^^
}
}
}
我不遵循这部分。属性是什么以及为什么按照其方式完成的?
好吧,因此您需要使用一个标题和CPP。为了使用它,您必须将C 变成C代码。这几乎是您在显示的DLL示例代码中看到的。但是,我确实建议您从标题中删除包含的内容,因为我不确定如何转化为C代码。将包含在CPP文件中。
我发现除了显示一大堆示例代码外,很难回答这个问题。完整代码在:https://github.com/ze413x/cpp-code-gems/其中,其中" csharpexamplescpp"呼叫来自mainwindow.xaml.cs的" csharpexlamecpp"呼叫" dllex amplame",该" dllex amplame"使用目录中的文件包含和源。
dll:
显示要使用的功能的标题:
#pragma once
#define DLLExport _declspec(dllexport)
extern "C" DLLExport void __cdecl GetCppText(char* str, int* strLength);
extern "C" DLLExport void __cdecl DLLPrint();
.cpp
#include "../includes/DLLExampleCode.h"
#include <string>
#include <iostream>
void __cdecl GetCppText(char* str, int* strLength)
{
std::string text = "This is called from within the DLL. ";
if (*strLength < text.length() || str == nullptr)
{
return;
}
memset((void*)str, 0, (*strLength) * sizeof(char));
strcpy_s(str, *strLength,text.c_str());
*strLength = text.length();
}
void __cdecl DLLPrint()
{
std::cout << "This is printed from inside DLLExample.dll.n";
}
c#:
using System.Runtime.InteropServices;
namespace CSharpExampleUsingCpp
{
public partial class MainWindow : Window
{
const string PATH = "DLLExample.dll";
[DllImport(PATH, CallingConvention = CallingConvention.Cdecl)]
public static unsafe extern void GetCppText(byte[] str, out System.Int32 strLength);
....
private void CppInteropButton_Click(object sender, RoutedEventArgs e)
{
System.Int32 size = 256;
System.Byte[] str = new byte[size];
for (int i = 0; i < size; i++)
{
str[i] = (byte)'1';
}
GetCppText(str, out size);
string result = System.Text.Encoding.UTF8.GetString(str, 0, size);
CppInteropButtonTextBox.Text = result;
}
尽管重读我获得字符串的解决方案可能不是最好的方法。您可能会围攻那件事,以避免所有这些愚蠢的chr*转换。当时我写它时,我可能有一些充分的理由。对于Google来说应该容易得多。
- 函数从唯一代码调用正确的子类方法
- 只允许授权代码调用库中的例程
- Android 无法从本机代码调用 Java 方法 JNI
- 如何从反应原生代码调用 C 函数?
- 如何在C++代码中使用 SVM Light?(可能无需从C++代码调用可执行文件)
- 如何从C代码调用PowerShell脚本
- 从 C 代码调用C++函数时出现问题
- 从 ObjC 代码调用 .mm 类方法时编译错误
- 代码调用反向函数不会在Ubuntu 18上的G 或Clang 上编译,但神秘地在Mac OSX上使用
- 如何使用C 代码调用MATLAB自定义函数
- 该代码调用副本或移动构造函数
- 无法在不同类上编译代码调用静态功能
- 如何从可从C++代码调用的 Ada 源代码构建静态库?
- 从 CPP 代码调用 Objective-C 方法
- 如何从C++代码调用 PL/pgSQL 函数
- C++如何判断static.lib是否有效,是否可从外部代码调用
- 当C代码调用Fortran子程序时,子程序顶部会出现分段错误
- JavaScript:从浏览器和 Node.js 中的 JavaScript 代码调用C++库
- C#到C代码P/调用多个std:字符串声明导致堆栈损坏
- 使用 Visual Studio 从C++代码调用程序集过程