c#调用dll接口传递utf-8字串方法
1. 起源:
VCU10之视频下载模块,采用纯python编码实现,c++代码调用pythonrun.h配置python运行环境启动python模块,编译为dll给c#调用,以使界面UI能够使用其中功能。
不要问为什么不用IronPython,它不是正统Python,且下载模块亦要为Mac产品所用。
棘手问题!用去一天时间反复打印日志,验证所传字串区别,以期望发现问题定位问题,直至下班前始有灵感。
验证发现,非中文字符可以正常下载,中文字符下载解析失败,当时即想到可能是字串不统一所致,就在python代码试遍字串编码转换,均不奏效。
原接口封装代码如下:
[DllImport("VideoDownloader", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private extern static bool VDDownload(IntPtr instance, string savePath, string imageSavePath,
string quality, string ext, string subtitleLang);
比如传savePath为[d:\vcu新],dll调用python模块,打印其编码信息:
print 'dir: ' + dir + ', code: ' + repr(dir))
则打印日志为:
dir: d:\kvd新, code: 'd:\\kvd\xd0\xc2'
而直接运行python代码,其输出却是:
dir: d:\kvd新, code: 'd:\\kvd\xe6\x96\xb0'
用c#建Demo用Encoding反解析验知\xd0\xc2为[新]字的gb2312编码,\xe6\x96\xb0为[新]字的utf-8编码。
2、字串编码
Win7 64位简体中文版中c#的默认编码:
做如此简单验证,发现其默认编码为gb2312;而所用python代码,为兼顾中文等多字节字符,默认采用utf-8编码。
问题大抵就在这里了,dll接口字串传递方式,需改为utf-8字串进行传递,但c#内置没有utf-8封装器,自定义实现它。
3、UTF8Marshaler
//接口数据为utf-8编码所设置
public class UTF8Marshaler : ICustomMarshaler
{
public void CleanUpManagedData(object managedObj)
{
} public void CleanUpNativeData(IntPtr pNativeData)
{
Marshal.FreeHGlobal(pNativeData);
} public int GetNativeDataSize()
{
return -;
} public IntPtr MarshalManagedToNative(object managedObj)
{
if (object.ReferenceEquals(managedObj, null))
return IntPtr.Zero;
if (!(managedObj is string))
throw new InvalidOperationException(); byte[] utf8bytes = Encoding.UTF8.GetBytes(managedObj as string);
IntPtr ptr = Marshal.AllocHGlobal(utf8bytes.Length + );
Marshal.Copy(utf8bytes, , ptr, utf8bytes.Length);
Marshal.WriteByte(ptr, utf8bytes.Length, );
return ptr;
} public object MarshalNativeToManaged(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero)
return null; List<byte> bytes = new List<byte>();
for (int offset = ; ; offset++)
{
byte b = Marshal.ReadByte(pNativeData, offset);
if (b == )
break;
else
bytes.Add(b);
}
return Encoding.UTF8.GetString(bytes.ToArray(), , bytes.Count);
} private static UTF8Marshaler instance = new UTF8Marshaler();
public static ICustomMarshaler GetInstance(string cookie)
{
return instance;
}
}
4、更新接口字串封送样式
[DllImport("VideoDownloader", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private extern static bool VDDownload(IntPtr instance,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]
string savePath,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]
string imageSavePath,
string quality, string ext, string subtitleLang);
验证工作OK!运行效果如下:
至此,一个技术难点解决,记录于此。
c#调用dll接口传递utf-8字串方法的更多相关文章
- C#程序实现动态调用DLL的研究(转)
摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...
- C#程序实现动态调用DLL的研究[转]
摘 要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...
- C#程序实现动态调用DLL的研究
摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...
- DLL接口自动化测试总结
1. DLL接口测试方法介绍 在最近测试的项目中,系统给业务端提供DLL文件,业务端通过DLL文件中的C++接口实现系统功能,这就需要对DLL中的C++接口进行详细功能测试. 本文主要介绍项目测试中使 ...
- 转【C#调用DLL的几种方法,包括C#调用C\C++\C#DLL】
C#中dll调用方法 一. DLL与应用程序 动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一, ...
- 【转】C#调用DLL
C#中如何调用动态链接库DLL(转) 每种编程语言调用DLL的方法都不尽相同,在此只对用C#调用DLL的方法进行介绍.首先,您需要了解什么是托管,什么是非托管.一般可以认为:非托管代码主要是基 ...
- android调用webservice接口获取信息
我的有一篇博客上讲了如何基于CXF搭建webservice,service层的接口会被部署到tomcat上,这一篇我就讲一下如何在安卓中调用这些接口传递参数. 1.在lib中放入ksoap2的jar包 ...
- python 调用RESTFul接口
本周需要将爬虫爬下来的数据入库,因为之前已经写好PHP的接口的,可以直接通过python调用PHP接口来实现,所以把方法总结一下. //python编码问题,因为好久用,所以很容易出现 # -*- c ...
- thinkjs学习-this.assign传递数据和ajax调用后台接口
在页面加载时,就需要显示在页面上的数据,可以在后台使用this.assign赋值,在前台通过ejs等模板获取:用户点击按钮,或者触发某些事件和后台进行交互时,就需要用到ajax调用后台接口.本文通过一 ...
随机推荐
- day09-数据库插入中文报错
在向数据库表中插入中文时一直报错 MySQL的默认编码是Latin1,不支持中文,要支持中文需要把数据库的默认编码修改为gbk或者utf8. 1.需要以root用户身份登陆才可以查看数据库编码方式(以 ...
- fb 4.7英文版 修改字体大小
windows-preferences-general-appearance-colors and fonts-basic-text font
- Java基础之用记事本编辑java代码运行,并且打成jar包后运行
使用记事本写java代码 1.在d盘新建一个记事本,名字叫做zhanzhuang.java,会询问不可用,是否继续,点击是 2.在里面编辑就如下内容,注意文件的名字要和 class 后面的名字相对应 ...
- css-实现子元素垂直居中
1.父元素:position:relative; 2.子元素:position:absolute; top:50%; transform:translate(0,-50%); 完美解决
- Pythagorean Triples 707C
Katya studies in a fifth grade. Recently her class studied right triangles and the Pythagorean theor ...
- How to Pronounce T + Dark L
How to Pronounce T + Dark L Share Tweet Share Tagged With: Dark L The T and Dark L combination is co ...
- 导入maven框架报错
原因pom文件第一行报错X org.apache.maven.archiver.mavenarchiver.getmanifest怎么解决 解决: 原因就是你的maven的配置文件不是最新的 1.he ...
- GIS案例学习笔记-水文分析河网提取地理建模
GIS案例学习笔记-水文分析河网提取地理建模 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:针对数字高程模型,通过水文分析,提取河网 操作时间:25分钟 数据 ...
- 前端Web安全介绍及规避。。。
本文转载自:https://jelon.top/posts/web-security/ 如果侵权,请及时告知. 一.跨站脚本攻击 (xss) 反射型跨站脚本攻击 攻击者会通过社会工程学手段,发送一个 ...
- tensorflow降低版本
tensorflow降低版本: pip install tensorflow==1.2.0 查看版本: import tensorflow as tf print(tf.__version__)