标题: [问题求助] powershell调用dll将汉字转为拼音 [打印本页]
作者: 小白龙 时间: 2023-3-14 13:34 标题: powershell调用dll将汉字转为拼音
本帖最后由 小白龙 于 2023-3-14 13:36 编辑
本人对Powershell和C++都不太懂
我想将下面链接的代码, 编译成dll, 然后在powershell中调用dll中的函数, 把汉字转为拼音
https://www.cnblogs.com/tangxin-blog/p/5541635.html
对于同时精通PS和C++两种语言的大佬, 可能是小case, 期待大佬能指引一下, 大致写个所用到的软件或工具及实现的过程,注意事项等, 非常感谢
应该有现成的转拼音的DLL了, 我上面是想通过大佬的指引, 以后也能自己修改和编译dll
作者: xczxczxcz 时间: 2023-3-14 16:00
你自己写一个PS就可以了。保留他原来的CODE部分,用来识别编号;
对输入的字符串用GBK编码一个一个判断。若为一个字节则保留原字符,2个字节则高位码在前低位码在后,大于160则减去160再把高位码乖100合成4位数再去查CODE。若4位查不到则输出原字符,可能是符号之类。
作者: pd1 时间: 2023-3-14 20:04
- extern "C" _declspec(dllexport)void h2p(const char* szChinese)
- {
- uint32_t bufLen = 0;
- char pinyinBuf[MAXBUFLEN] = { 0 };
- //const char* szChinese = "中华人民共和国 People's Republic of China";
- getPinyin(szChinese, pinyinBuf, MAXBUFLEN, &bufLen, enmPinyinMode_FirstUpper);
- printf("%s\n", pinyinBuf);
- }
复制代码
- $code=@"
- using System;
- using System.Runtime.InteropServices;
- public static class Api{
- [DllImport("C:/Users/Administrator/source/repos/test/x64/Release/test.dll")]
- public static extern int h2p(String ss);
- }
- "@
- Add-Type -TypeDefinition $code
- [Api]::h2p("我是中国人")
复制代码
作者: Five66 时间: 2023-3-14 20:07
直接编译成dll只能以p/invoke方式调用.为了兼容性,用msvc,软件就是visual studio(图形界面)或visual studio build tools(字符界面).注意要在编译选项给出导出函数或在源码需要导出的函数前加上
__declspec(dllexport)
想要在ps直接使用,需要转成c++/cli的代码并且以/clr的编译选项编译成dll,有点麻烦
其实也可以直接在ps里写个文字跟拼音的hashtable,然后索引就行了
(有多音字的存在,不管怎么样都不会100%准确)
作者: 小白龙 时间: 2023-3-14 20:21
回复 4# Five66
多谢大佬指导, 我现在大致明白了思路, VS太大了, 有没有其它的编译小工具呢? 在PS中写函数, 感觉执行速度会慢, 应该没有调用dll快
:
作者: czjt1234 时间: 2023-3-14 20:23
https://www.yisu.com/zixun/404214.html
vbs行不行
作者: 小白龙 时间: 2023-3-14 20:23
本帖最后由 小白龙 于 2023-3-14 20:28 编辑
回复 3# pd1
多谢大佬指导, 现在代码和事项都有了, 就差编译dll了, 我不装vs有别的方式编译DLL吗, 以前看到过文章可以用什么tcc编译器搞,但是不知道怎么搞
作者: 小白龙 时间: 2023-3-14 20:25
回复 6# czjt1234
多谢大佬指导, 这个贴子, 我主要是想学习下, 编译C或C++为DLL, 然后在PS中调用DLL的方法和事项
作者: 小白龙 时间: 2023-3-14 20:27
本帖最后由 小白龙 于 2023-3-14 20:33 编辑
回复 2# xczxczxcz
多谢大佬指导, 我懂的太浅了, 自己搞不了 有现成的轮子, 就不自己搞了
作者: 小白龙 时间: 2023-3-14 20:32
本帖最后由 小白龙 于 2023-3-14 20:34 编辑
回复 4# Five66
大佬, 我对下面这句话不太懂, DLL能在PS下直接使用? 怎么直接使用, 有代码吗? 麻烦点也想尝试下, 有文章链接吗? 我想试试
想要在ps直接使用,需要转成c++/cli的代码并且以/clr的编译选项编译成dll,有点麻烦
作者: Five66 时间: 2023-3-14 20:56
回复 10# 小白龙
除了vs还可以使用gcc(mingw)或clang(llvm),vs因为包含各种平台跟目标平台(x86,x64,arm,arm64....)才这么大的,只能安装后自行精简
ps编译成可以直接使用dll,可以参考
https://learn.microsoft.com/zh-cn/previous-versions/ms235281(v=vs.120)
编译成dll后(只能使用msvc,即vs编译),ps里直接add-type之类添加dll就行了
作者: Five66 时间: 2023-3-14 21:03
回复 11# Five66
还有种方法,用C#生成一个调用C++的封装类的dll,ps里也可以直接使用
作者: went 时间: 2023-3-14 21:49
本帖最后由 went 于 2023-3-14 21:54 编辑
64位dll & 调用
pinyin.rar
作者: 小白龙 时间: 2023-3-14 21:56
回复 3# pd1
大佬能指导下吗?
我没有装VS,看了点教程用Tcc编译, 会报下面的错误,
tcc: undefined symbol 'isascii'
我把报错的(// 排除askii 码 )那几行代码删了, 能编译成功, 但是在PS中执行又报下面的错误
Add-Type : c:\Users\Administrator\AppData\Local\Temp\30bxsszt\30bxsszt.0.cs(4) : 无法识别的转义序列
下面是编译的C代码前面的部分, 贴全部就超长了- #include <string.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <ctype.h>
-
- #define EXPORT __declspec(dllexport)
- #define MAXBUFLEN 1024
-
- enum PinyinMode{
- enmPinyinMode_AllUpper = 0, //全大写
- enmPinyinMode_AllLower, //全小写
- enmPinyinMode_FirstUpper, //首字母大写
- };
-
- const char* getPinyinByCode(uint32_t code);
- void getPinyin(const char* szChinese,char pinyinBuf[],const uint32_t maxBufLen,uint32_t *bufLen,const uint32_t mode);
-
- EXPORT void h2p(const char* szChinese)
- {
- uint32_t bufLen = 0;
- char pinyinBuf[MAXBUFLEN] = { 0 };
- //const char* szChinese = "中华人民共和国 People's Republic of China";
- getPinyin(szChinese, pinyinBuf, MAXBUFLEN, &bufLen, enmPinyinMode_FirstUpper);
- printf("%s\n", pinyinBuf);
- }
-
- void getPinyin(const char* szChinese,char pinyinBuf[],const uint32_t maxBufLen,uint32_t *bufLen,const uint32_t mode)
- {
- *bufLen = 0;
- uint8_t ucHigh, ucLow;
- uint32_t code,i,j;
- const uint32_t chineseLen = strlen(szChinese);
- for (i = 0; i<chineseLen;++i )
- {
- uint8_t c = szChinese[i];
- // 排除askii 码
- if (isascii(c))
- {
- pinyinBuf[(*bufLen)++] = c;
- continue;
- }
- ucHigh = (uint8_t)szChinese[i];
- ucLow = (uint8_t)szChinese[++i];
- if ( ucHigh <= 0xa0 || ucLow <= 0xa0 )
- {
- continue;
- }
- else
- {
- code = (ucHigh - 0xa0) * 100 + ucLow - 0xa0;
- }
- const char* pBuf = getPinyinByCode(code);
- for (j = 0; j < strlen(pBuf) && (*bufLen) < maxBufLen; ++j)
- {
- char cc = pBuf[j];
- switch(mode)
- {
- case enmPinyinMode_AllUpper:break;
- case enmPinyinMode_AllLower:cc = tolower(cc);break;
- case enmPinyinMode_FirstUpper:if(j!=0)cc = tolower(cc);break;
- }
- pinyinBuf[(*bufLen)++] = cc;
- }
- }
- }
-
- }
复制代码
作者: 小白龙 时间: 2023-3-14 21:58
回复 13# went
多谢大佬, 您用什么编译的? 我用tcc编译会报上面的错误, 另外我的电脑是32位的, 应该用不了64位dll
作者: 小白龙 时间: 2023-3-14 22:00
回复 12# Five66
大佬能给指导一下上面tcc编译报错的问题吗? 装VS太麻烦了
作者: went 时间: 2023-3-14 22:10
试试这个32位的,替换ps1文件夹里面的dll
https://went.lanzouw.com/inU060q3dkqj
winddk命令行编译
作者: 小白龙 时间: 2023-3-14 22:24
本帖最后由 小白龙 于 2023-3-14 22:25 编辑
回复 17# went
封装的函数名怎么看?
用下面的代码执行报错
Add-Type : c:\Users\Administrator\AppData\Local\Temp\ixzwysxg\ixzwysxg.0.cs(4) : 无法识别的转义序列
c:\Users\Administrator\AppData\Local\Temp\ixzwysxg\ixzwysxg.0.cs(3) : public static class Api{
c:\Users\Administrator\AppData\Local\Temp\ixzwysxg\ixzwysxg.0.cs(4) : >>> [DllImport("C:\Users\Administrator\Deskto
p\MyDll.dll")]
c:\Users\Administrator\AppData\Local\Temp\ixzwysxg\ixzwysxg.0.cs(5) : public static extern int h2p(String ss);
At line:9 char:1
+ Add-Type -TypeDefinition $code
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Microsoft.Power...peCompilerError:AddTypeCompilerError) [Add-Type], Exce
ption
+ FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand- $code=@"
- using System;
- using System.Runtime.InteropServices;
- public static class Api{
- [DllImport("C:\Users\Administrator\Desktop\MyDll.dll")]
- public static extern int h2p(String ss);
- }
- "@
- Add-Type -TypeDefinition $code
- [Api]::h2p("我是中国人")
复制代码
作者: 小白龙 时间: 2023-3-14 22:29
回复 17# went
这里有个tcc编译的教程, 下载安装配置都很顺利, 就是报前面的错误, 大佬帮看一下就太感谢了,
http://www.taodudu.cc/news/show-4919115.html
作者: went 时间: 2023-3-14 22:35
isascii函数未定义,检查ctype.h文件
'\'符号需要转义,'\\'
作者: went 时间: 2023-3-14 23:13
winddk编译c&c++
mini工具包下载 支持xp
https://went.lanzouw.com/irKAW0q3gbbi
作者: Five66 时间: 2023-3-14 23:28
回复 16# 小白龙
试试将isascii(c)改成 c < 0x80
作者: 小白龙 时间: 2023-3-14 23:30
本帖最后由 小白龙 于 2023-3-14 23:32 编辑
回复 21# went
多谢大佬指导,
https://www.cnblogs.com/tangxin-blog/p/5541635.html
我直接用上面的链接的C代码, 拷到PSPad中, 然后TCC编译, 一下就能生成exe, 编译速度非常快, 但是修改main函数为下面代码就报错了, 应该要改一下代码
各位大佬可以按下面的链接试一下TCC编译器, 才几百K
http://www.taodudu.cc/news/show-4919115.html- extern "C" _declspec(dllexport)void h2p(const char* szChinese)
- {
- uint32_t bufLen = 0;
- char pinyinBuf[MAXBUFLEN] = { 0 };
- //const char* szChinese = "中华人民共和国 People's Republic of China";
- getPinyin(szChinese, pinyinBuf, MAXBUFLEN, &bufLen, enmPinyinMode_FirstUpper);
- printf("%s\n", pinyinBuf);
- }
复制代码
作者: 小白龙 时间: 2023-3-14 23:41
本帖最后由 小白龙 于 2023-3-14 23:43 编辑
回复 22# Five66
多谢大佬指导, 改完之后不再报错了, 也能输出了, 但是输出是错的, 我想输出 中国人 的拼音, 但是显示的拼音是 Juan?Bang
我把main改为了如下- __declspec(dllexport) void h2p(const char* szChinese)
- {
- uint32_t bufLen = 0;
- char pinyinBuf[MAXBUFLEN] = { 0 };
- //const char* szChinese = "中华人民共和国 People's Republic of China";
- getPinyin(szChinese, pinyinBuf, MAXBUFLEN, &bufLen, enmPinyinMode_FirstUpper);
- printf("%s\n", pinyinBuf);
- MessageBox(0, pinyinBuf, "title", MB_TOPMOST);
- }
复制代码
作者: 小白龙 时间: 2023-3-15 00:29
本帖最后由 小白龙 于 2023-3-15 00:31 编辑
回复 21# went
大佬, 下载后试了一下您的全套, 还是报错, 应该可能是64位dll原因, 我再试下32位的
Exception calling "getPinyin" with "5" argument(s): "试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)"
At C:\Users\Administrator\Desktop\pinyin\test.ps1:17 char:1
+ [Api]::getPinyin($src,$buf,1024,[ref]$len,2)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ( [], MethodInvocationException
+ FullyQualifiedErrorId : BadImageFormatException- cls
- $code=@"
- using System;
- using System.Runtime.InteropServices;
- public static class Api{
- [DllImport("pinyin.dll")]
- public static extern void getPinyin(byte[] src,byte[] buf,uint max_len,ref uint buf_len,uint mode);
- }
- "@
- Add-Type -TypeDefinition $code
-
- $s = "中华人民共和国 People's Republic of China"
-
- $src=[System.Text.Encoding]::Default.GetBytes($s)
- $buf = New-Object 'byte[]'(1024)
- $len = 0
- [Api]::getPinyin($src,$buf,1024,[ref]$len,2)
-
- [System.Text.Encoding]::Default.GetString($buf,0,$len)
复制代码
作者: went 时间: 2023-3-15 00:45
修改pinyin.c文件第一行 再拖到bat文件上重新编译dll
x86或x64都试试
作者: 小白龙 时间: 2023-3-15 01:07
回复 26# went
多谢大佬, 用这个 //config=x64 编译的成功了, 是不是反了? 现在生成的文件小点了
作者: 小白龙 时间: 2023-3-15 01:08
回复 26# went
您早点休息吧, 太感谢了
作者: Five66 时间: 2023-3-15 01:58
回复 24# 小白龙
你的"中国人"是utf8编码的,utf8编码的"中国人"前面两字节是0xe4和0xb8,执行代码 (0xe4-0xa0)*100+(0xb8-0xa0) 后是 6824 ,对应代码 case 6824(返回拼音 "JUAN")
而gbk编码的"中国人"前面两字节是0xd6和0xd0,执行代码 (0xd6-0xa0)*100+(0xd0-0xa0) 后是 5448 ,对应代码:
if(code>=5448 && code<=5458)
{
return "ZHONG";
break;
}
作者: Five66 时间: 2023-3-15 03:49
睡不着弄了个能直接调用的dll(64位的dll,包含源码,只是加了个类),有兴趣的就看看吧
点击下载
作者: 小白龙 时间: 2023-3-15 11:28
回复 30# Five66
多谢大佬, 下载链接提示没有文件
作者: pd1 时间: 2023-3-15 11:44
回复 14# 小白龙
我用的vs2019。小白一个,对原理,报错啥的我都不怎么会,只是点一下按钮生成一下。
我用的dll
https://t.wss.ink/f/aq9mrsmo32b 复制链接到浏览器打开
作者: 小白龙 时间: 2023-3-15 14:21
本帖最后由 小白龙 于 2023-3-15 14:23 编辑
回复 32# pd1
报下面的错误
Add-Type : c:\Users\Administrator\AppData\Local\Temp\k2gzgzki\k2gzgzki.0.cs(4) : 无法识别的转义序列
生成的dll文件, 太小了, 只有30来k
我用tcc生成的70多k , 用went大佬winddk生成的100多k
作者: pd1 时间: 2023-3-15 14:49
回复 33# 小白龙
64位的,我这边正常。其他的不清楚
作者: Five66 时间: 2023-3-15 16:56
回复 31# 小白龙
换了个下载地址,打开下面的地址后等待10秒左右点击download就行了
http://ybshare.com/download/y7ihz8g6jy
作者: 小白龙 时间: 2023-3-15 19:44
回复 35# Five66
会报下面的错误, 我的系统 win7 ps5.1 x64
Add-Type : 未能加载文件或程序集“new.dll”或它的某一个依赖项。找不到指定的模块。
At C:\Users\Administrator\Desktop\pinyin\test.ps1:1 char:1
+ Add-Type -LiteralPath new.dll
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ( [Add-Type], FileNotFoundException
+ FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.AddTypeCommand
Unable to find type [the.api].
At C:\Users\Administrator\Desktop\pinyin\test.ps1:2 char:4
+ $a=[the.api]::new()
+ ~~~~~~~~~
+ CategoryInfo : InvalidOperation: (the.api:TypeName) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
You cannot call a method on a null-valued expression.
作者: Five66 时间: 2023-3-15 20:48
回复 36# 小白龙
dll有vc依赖项,为:
VCRUNTIME140.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
需要安装vc++之类的运行库
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |