c# 调用DLL 参数问题

wenyiyi 2010-12-25 11:53:23
我现在遇到一个问题。 是调用一个dll。 发现其参数是有指针。不知道应该如何写。

int FL_GetFea(int nAddr, unsigned char* pTemplet, int* iTempletLength);



我改写成下面那样出现了错误

public static extern int FL_GetFea(int nAddr, IntPtr pTemplet, IntPtr iTempletLength);

int fl_GetFea(int nAddr, string pTemplet, int iTempletLength)
{
return FL_GetFea(nAddr, pTemplet, iTempletLength);
}
...全文
131 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
prosoul 2010-12-25
  • 打赏
  • 举报
回复
等待学习中
wenyiyi 2010-12-25
  • 打赏
  • 举报
回复
TO 5楼

public static extern int FL_GetFea(int nAddr, IntPtr pTemplet, IntPtr iTempletLength);

int aAddr;
StringBuilder sb = new StringBuilder(256);
int length = 256;
int fl_GetFea1(int nAddr, StringBuilder sb, ref int length)
{

FL_GetFea(nAddr, sb, ref length);
}
我写成这样还是有错误。 无效参数
wenyiyi 2010-12-25
  • 打赏
  • 举报
回复
TO 5楼 我去试下
wenyiyi 2010-12-25
  • 打赏
  • 举报
回复
感谢楼上的几位同志参与回复。
TO 3楼 能针对 int FL_GetFea(int nAddr, unsigned char* pTemplet, int* iTempletLength);
改写下吗? 谢谢

To 4楼 我好好看看。谢谢


  • 打赏
  • 举报
回复
int FL_GetFea(int nAddr, unsigned char* pTemplet, int* iTempletLength);
第二个参数是一个字符串指针,应该是用来写数据的
第三个参数在传入的时候应该是指明第二个参数的长度,在传出的时候指明实际写了多少字节数据
试试这样:
int aAddr;
StringBuilder sb = new StringBuilder(256);
int length = 256;
GetFea(nAddr, sb, ref length);
ghlfllz 2010-12-25
  • 打赏
  • 举报
回复
引自:http://blog.csdn.net/ghlfllz/archive/2010/10/10/5931291.aspx

有两种办法在C#中调用C++写的DLL的方法有两种:

1、COM

将C++代码封装成COM,然后在C#中引用

2、API

将C++代码封装成C接口的函数,类似于Windows的API,然后在C#中通过DllImport引用

例如:

c++头文件为

int _stdcall Decrypt(unsignec char *src, unsigned long src_len, unsigned char **dst, unsigned long *dst_len);

注:在*.def文件中需呀为定义Decrypt的导出

在c#中引用如下命名空章

using System.Runtime.InteropServices;

在某个类的构造函数后面添加:

[DllImport("CryptTools.dll")]

internal static extern int Decrypt(System.IntPtr src, int src_len, ref System.IntPtr dst, ref int dst_len);

添加函数封装对该API的调用:

internal static int Sharp_Decrypt(byte[] src, ref byte[] dst)

{

int result = -1, dstLen = 0;

IntPtr pSrc = Marshal.AllocHGlobal(src.Length);

Marshal.Copy(src, 0, pSrc, src.Length);

IntPtr pDst = IntPtr.Zero;

result = Decypt(pSrc, src.Length, ref pDst, ref dstLen);

if (0 == result)

{

dst = new byte[dstLen];

Marshal.Copy(pDst, dst, 0, dstLen);

}

Marshal.FreeHGlobal(pSrc);

return result;

}

请注意,出于篇幅的考虑,此处没有在CryptTools.dll中添加unsigned char**的释放函数,需要读者自行添加。
快溜 2010-12-25
  • 打赏
  • 举报
回复
试试参数用ref。
wenyiyi 2010-12-25
  • 打赏
  • 举报
回复
一同等待吧。在这孤单的节日里,唯有代码能让我那冰冷的心灵暖和起来。。。。
哥又能写诗了!哦也!
lkr2380869 2010-12-25
  • 打赏
  • 举报
回复
等待学习
garfieldzf 2010-12-25
  • 打赏
  • 举报
回复

[DllImport()]
public static extern int FL_GetFea(int nAddr,ref byte[] pTemplet,ret int iTempletLength);
pTemplet, iTempletLength 可能是输入参数。
你看看API,


参数类型对照:http://www.cnblogs.com/yufb/archive/2010/06/02/1749838.html
wenyiyi 2010-12-25
  • 打赏
  • 举报
回复
To yangglemu
谢谢了。我照你的再去修改下。 头一次调用DLL,对C++也不熟悉。很多东西都不明白。
  • 打赏
  • 举报
回复
我对最后一个参数的方法有误,写了点代码测试了一下:
C/C++ Dll代码:
#include "stdafx.h"
#include <stdio.h>

extern "C" __declspec(dllexport) void GetName(char* buffer, int* size)
{
printf("before copy the length is:%d\n", *size);//写数据前buffer的容量
char temp[] = "hello,world";
strcpy(buffer,temp); //模拟写数据
printf("OK, string is:%s\n", buffer);
*size = (int)strlen(temp);
printf("after copy the length is:%d\n", *size);//写数据后buffer的容量
}


C#调用代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ConsoleApplication3
{
class Program
{
[DllImport("MyDll.dll")]
private extern static void GetName(StringBuilder sb, IntPtr length);

static void Main(string[] args)
{
StringBuilder sb = new StringBuilder(256);
IntPtr ptr = Marshal.AllocHGlobal(sizeof(int));//申请一个整数指针
Marshal.WriteInt32(ptr, sb.Capacity);//给指针内容赋初值为缓冲区容量

GetName(sb, ptr);//调用Dll函数
//可以在这里测试SB的实际内容/长度,来测试DLL函数是否正确执行
Marshal.FreeHGlobal(ptr);

}
}
}

以上代码经过测试,输出正确

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧