2016-11-09 52 views
0

有一个在C代码(之一):如何从UWP中的DLL调用函数?

 void Function(char *output, size_t size); 

有代码在C#:

[DllImport(@"C:\path\Name.dll", 
       CallingConvention = CallingConvention.Cdecl, 
       CharSet = CharSet.Ansi, EntryPoint = "Function")] 
    static extern void Function([In, Out] StringBuilder output, 
           [In, MarshalAs(UnmanagedType.SysUInt)] UIntPtr size); 

如果我调用该函数的应用程序失败,出现此错误:

Unable to load DLL 'C:\path\Name.dll': Access denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) 

什么是错的?我必须做什么?

+0

您有两个问题1)您必须在调用DLL之前分配变量输出。 char [] output = new char [256](); 2)c#中的字符是两个字节,而在c中是一个字节。通常你应该使用byte []而不是char []。 – jdweng

+0

@jdweng如果我调用另一个没有params应用程序的方法失败,出现此错误。 (对不起,我的英语不好) –

+0

查看帖子:https://stackoverflow.com/questions/38146181/passing-a-char-array-from-c-sharp-to-c-dll。使用byte []而不是char []。不要使用String Builder。 – jdweng

回答

0

将DLL添加到您的项目中,并将其设置为在输出目录中复制的内容类型。

[DllImport(@"Name", 
       CallingConvention = CallingConvention.StdCall, 
       CharSet = CharSet.Ansi, EntryPoint = "Function")] 
    static extern void Function([In, Out] StringBuilder output, 
           [In, MarshalAs(UnmanagedType.SysUInt)] UIntPtr size); 

这就是由SqlLite进行(例如:那么这种方式(不添加扩展名“.DLL”引用它https://github.com/praeclarum/sqlite-net/blob/master/src/SQLite.cs):)

正如jdweng指出的那样,你可能希望也可以使用byte []来代替StringBuilder。

+0

如果我写这个,应用程序找不到dll:[DllImport(@“Name”)。如果我编写[DllImport(@“../ Name”应用程序失败,出现旧错误,我不知道该怎么办( –

+0

可能是在UWP中没有实现的DLL使用API​​?(这个DLL不是我创建的) –

+0

我不知道这个,也许是需要改变的调用约定,试着使用CallingConvention.Cdecl吧? –