将具有参数(char *)的C ++ DLL函数加载到C#中 [英] loading c++ dll function having parameter (char * ) into c#

查看:98
本文介绍了将具有参数(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''.

推荐答案

您需要使用
You need to use Marshaling[^].

C++ takes a string as the raw ASCII (for char *) data, followed by a single byte with the value of 0. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆