C# DllImport C夏普常量字符*

C# DllImport C夏普常量字符*,c#,C#,何乐而不为 我想在C#中从非托管dll转换为托管dll 在文件中,它是: typedef void* AP_HANDLE typedef uint32_t ap_u32 AP_HANDLE ap_CreateVirtual(const char *szFilename) void ap_SetState(AP_HANDLE apbase, const char *szState, int nValue) unsigned char *ap_ColorPipe(AP_HANDLE

何乐而不为

我想在C#中从非托管dll转换为托管dll

在文件中,它是:

typedef void*    AP_HANDLE
typedef uint32_t ap_u32

AP_HANDLE ap_CreateVirtual(const char *szFilename)

void ap_SetState(AP_HANDLE apbase, const char *szState, int nValue)

unsigned char *ap_ColorPipe(AP_HANDLE      apbase, 
                            unsigned char *pInBuffer,
                            ap_u32         nInBufferSize, 
                            ap_u32        *rgbWidth, 
                            ap_u32        *rgbHeight, 
                            ap_u32        *rgbBitDepth)
C++中的P>工作得很好,但是在C语言中语法是问题所在。 看来我不能让evan第一个功能不工作

public unsafe class appbase
{
    [DllImport("D:\\apbase.dll", EntryPoint = "ap_CreateVirtual")]
    //, CharSet = UnicodeEncoding
    //, CallingConvention = CallingConvention.StdCall

    public static extern void* ap_CreateVirtual(char* szFilename);
}

尝试使用ap_CreateVirtual string、string*、char*、char[]的参数,并在返回时放置断点;ap_句柄的值始终为0x0000


导入这些函数的正确方法是什么?

char*
是.NET字符串的默认封送处理

[DllImport("D:\\apbase.dll", EntryPoint = "ap_CreateVirtual", CharSet = CharSet.Ansi)]
//, CallingConvention = CallingConvention.StdCall
public static extern System.IntPtr ap_CreateVirtual(string szFilename);
<>你原来的尝试是错误的,因为< C >中的代码> char < /C> >是C++的代码> WCARGYTT < /C>,不是C++ >代码> char < /C> >

如果在C++中需要一个C++ <代码> char ,它不是<代码>字节<代码>,就是<代码> sByth。但是p/invoke只需对

System执行正确的操作。String

char*
是.NET字符串的默认封送处理

[DllImport("D:\\apbase.dll", EntryPoint = "ap_CreateVirtual", CharSet = CharSet.Ansi)]
//, CallingConvention = CallingConvention.StdCall
public static extern System.IntPtr ap_CreateVirtual(string szFilename);
<>你原来的尝试是错误的,因为< C >中的代码> char < /C> >是C++的代码> WCARGYTT < /C>,不是C++ >代码> char < /C> >

如果在C++中需要一个C++ <代码> char ,它不是<代码>字节<代码>,就是<代码> sByth。但是,p/Unjk只会在<代码>系统> String >

< P>中做正确的事情。仅仅在C++头上复制是不够的。您需要理解这些参数的实际含义以及它们是如何表示的。第一个函数非常简单:

[DllImport("...", EntryPoint="ap_CreateVirtual")]
public static extern IntPtr ap_CreateVirtual(
  [In, MarshalAs(UnmanagedType.LPStr)] string szFilename);

我假设在第二种情况下,
szState
也是一个简单的LPStr,而
pInBuffer
很可能是一个固定长度的
byte[]
,其大小由
nInBufferSize
确定
rgbXXX
似乎是
ref
参数。返回类型可能是一个LpSTR。

< P>只是在C++头上复制是不够的。您需要理解这些参数的实际含义以及它们是如何表示的。第一个函数非常简单:

[DllImport("...", EntryPoint="ap_CreateVirtual")]
public static extern IntPtr ap_CreateVirtual(
  [In, MarshalAs(UnmanagedType.LPStr)] string szFilename);

我假设在第二种情况下,
szState
也是一个简单的LPStr,而
pInBuffer
很可能是一个固定长度的
byte[]
,其大小由
nInBufferSize
确定
rgbXXX
似乎是
ref
参数。返回类型也可以是LPStr。

如果CharSet=CharSet.Ansi,则返回类型将被分解,如果CharSet=CharSet.Unicode,则返回类型将被传递,但在。。。所以它不适用于CharSet=CharSet.Ansi,它会崩溃,而CharSet=CharSet.Unicode会通过,但指针在。。。所以它不工作了,在调用s=“D:\\ASX.xsdat”之后,它似乎仍然出现故障;ap_创建虚拟设备@dorin.petre这很可能意味着您也需要更改调用约定,可能需要更改为
CallingConvention.Cdecl
(正确的调用约定应该是文档的一部分,但如果不是,Cdecl可能就是您想要的C风格函数的调用约定)。此外,请确保本机DLL和应用程序具有相同的位-.NET应用程序默认为AnyCPU,因此在64位系统上,它们将无法调用32位本机DLL。到底是什么“故障”?在调用s=“D:\\ASX.xsdat”之后,它似乎仍然故障;ap_创建虚拟设备@dorin.petre这很可能意味着您也需要更改调用约定,可能需要更改为
CallingConvention.Cdecl
(正确的调用约定应该是文档的一部分,但如果不是,Cdecl可能就是您想要的C风格函数的调用约定)。此外,请确保本机DLL和应用程序具有相同的位-.NET应用程序默认为AnyCPU,因此在64位系统上,它们将无法调用32位本机DLL。到底什么是“故障”?