将具有参数(char *)的C ++ DLL函数加载到C#中 [英] loading c++ dll function having parameter (char * ) into c#
本文介绍了将具有参数(char *)的C ++ DLL函数加载到C#中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我已经在vc ++中创建了dll
i have created dll in vc++
init_set(char *)
需要char *
takes char *
extern "C" MYDLL_API int init_set(char*);
extern "C" MYDLL_API int init_valid();
在C#中,我想将字符串传递给init_set().
in c# i want to pass an string to init_set().
[DllImport("MYDLL.dll")]
public static extern int init_set(char[] s);
[DllImport("MYDLL.dll")]
public static extern int init_valid();
在主要
in main
static void Main(string[] args)
{
string st = "Quad127";
char[] s = st.ToCharArray();
init();
init_set(s);
所有void函数都会运行,但这会给出消息
all void function runs but this gives message
An unhandled exception of type ''System.EntryPointNotFoundException'' occurred in usedll.exe
Additional information: Unable to find an entry point named ''init_set'' in DLL ''MYDLL.dll''.
推荐答案
您需要使用 ^ ].
C ++将字符串作为原始ASCII(对于char *
)数据,后跟一个值为0
的单个字节.不知道C#如何存储它的字符串,但是我敢打赌那里存储了一个长度.
因此,一个非常简单的示例:
MYDLL.cpp:
You need to use Marshaling[^].
C++ takes a string as the raw ASCII (forchar *
) data, followed by a single byte with the value of0
. Not sure how C# stores it''s string, but I bet there is a length stored in there somewhere.
So, a very simple example:
MYDLL.cpp:
#include <Windows.h>
#include <stdio.h>
//MUST have extern "C" if in C++, otherwise the name will be mangled
extern "C" __declspec(dllexport) int init_set(char *sz) {
printf("%s\n", sz);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD nReason, LPVOID lpReserved) {
return TRUE;
}
和C#文件:
and the C# file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices; //has the Marshal class
namespace CS_CLI
{
class Program
{
[DllImport("MYDLL.dll")]
public static extern int init_set(IntPtr s); //The type is a pointer (to characters) in C, so we need to say this, with IntPtr
static void Main(string[] args)
{
String str = "I am a managed String"; //Some random string
IntPtr ptrCString = (IntPtr)Marshal.StringToHGlobalAnsi(str); //Our actual marshal. This creates a copy of the string in unmanaged memory. This also converts the unicode string used in C# to ascii (char* is ASCII, wchar_t* is Unicode)
init_set(ptrCString); //Call our function
Marshal.FreeHGlobal(ptrCString); //Free the copy of the memory we made 2 lines above
}
}
}
我刚刚按如下所示创建了一个简单的DLL,它创建了正确的链接,并且我的C#测试程序可以调用这些方法:
1.头文件( zzdll.h )
I have just created a simple DLL as follows, which creates the correct linkage, and my C# test program can invoke the methods:
1. Header file (zzdll.h)
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
extern "C" MYDLL_API int __stdcall init_set(char*);
extern "C" MYDLL_API int __stdcall init_valid();
2.执行文件( zzdll.cpp )
2. Implementation file (zzdll.cpp)
#include "zzdll.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
MYDLL_API int __stdcall init_set(char*)
{
return 1;
}
MYDLL_API int __stdcall init_valid()
{
return 1;
}
标签MYDLL_EXPORTS
是为编译器定义的.
[edit]
添加了__stdcall
以实现正确的功能链接.
[/edit]
The tag MYDLL_EXPORTS
is defined to the compiler.
[edit]
Added __stdcall
for correct function linkage.
[/edit]
这篇关于将具有参数(char *)的C ++ DLL函数加载到C#中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文