gpt4 book ai didi

raku - 如何使用 NativeCall 从 Perl 6 中正确使用 libXL?

转载 作者:行者123 更新时间:2023-12-04 08:44:50 26 4
gpt4 key购买 nike

我尝试使用来自 Perl 6(最新版本)的 libXL 和 NativeCall .
我无法让 utf-8 正确保存创建的 xlsx 文件。
只有 CArray[uint16]似乎工作,也没有编码 Str('utf8') 或 CArray[uint8] .
最佳结果是保存工作簿、工作表名称和文本;但通常它们以特殊符号结尾。即使设置 key 也“经常”起作用。
我的猜测是需要 utf-8 但 CArray[uint16]总是给出两个字节,而 utf-8 是一种动态格式。我的猜测也是,我对 libXL.dll 的签名可能是错误的。
我还尝试了适用于 xls 的函数的 A-DLL 版本,但我想获得 xlsx(XML 格式)。
我试图更改 NativeCall 的子签名并尝试了不同格式的给定变量。

use v6;

use NativeCall;

constant PathLibXL = "C:/....../libxl-3.8.5.0/bin64/libxl.dll";

sub xlBookSaveW(int32, CArray[uint16]) returns uint8 is native(PathLibXL) {*}; # int xlBookSave(BookHandle handle, const wchar_t* filename)
sub xlBookAddSheetW(int64, CArray[uint16]) returns int64 is native(PathLibXL) {*}; # SheetHandle xlBookAddSheet(BookHandle handle, const wchar_t* name, SheetHandle initSheet)
sub xlBookErrorMessageW(int64) returns Str is encoded('utf8') is native(PathLibXL) {*}; # const char* xlBookErrorMessage(BookHandle handle)
sub xlBookReleaseW(int64) is native(PathLibXL) {*}; # void xlBookRelease(BookHandle handle)
sub xlBookSetKeyW(int64, CArray[uint16], CArray[uint16]) is native(PathLibXL) {*}; # void xlBookSetKey(BookHandle handle, const wchar_t* name, const wchar_t* key)
sub xlCreateBookW() returns int64 is native(PathLibXL) {*}; # Book* xlCreateBook()
sub xlCreateXMLBookW() returns int64 is native(PathLibXL) {*}; # Book* xlCreateBook()
sub xlSheetWriteStrW(int64, int64, int64, CArray[uint16], int64) returns int64 is native(PathLibXL) {*}; # int xlSheetWriteStr(SheetHandle handle, int row, int col, const wchar_t* value, FormatHandle format)


sub test-nativeW(){
my $format = 'utf-8'; # utf8 utf16 utf16le utf16be utf8-c8 iso-8859-1 windows-1251 windows-1252 windows-932 ascii
my $Nr = (11111..99999).rand.Int;

my $sheetName16 = CArray[uint16].new("SheetTest".encode($format).list);
my $text = CArray[uint16].new("Hello, world!".encode($format).list);
my $savePath16 = CArray[uint16].new("C:/Temp/Test.$Nr.perl6.xlsx".encode($format).list);


my $book = xlCreateXMLBookW();
if $book > 0 {
say "savePath16:" ~ $savePath16;

my $name = CArray[uint16].new("DELETED".encode($format).list);
my $key = CArray[uint16].new("DELETED".encode($format).list);

xlBookSetKeyW($book, $name, $key);

say "book:" ~ $book;
say "sheetName16: $sheetName16";

my $sheet = xlBookAddSheetW($book, $sheetName16);

if $sheet > 0 {
say "sheet: $sheet";

xlSheetWriteStrW($sheet, 0, 0, $text, 0);

}else{
say "sheet: $sheet";

my $errMsg = xlBookErrorMessageW($book);

say "error:{ $errMsg.Str }";
}

say "C:/Temp/Test.$Nr.perl6.xlsx".encode($format).Str;

my $R = xlBookSaveW($book, $savePath16);

if $R > 0 {
say "releasing book...";
xlBookReleaseW($book)
}

}else{
say "book:" ~ $book;

my $errMsg = xlBookErrorMessageW($book);

say "error:{ $errMsg.Str }";
}
}

test-nativeW();
  • 有时,没有保存任何内容,并且代码从 Perl 6 以非 0 代码结束
  • 有时,文件名以特殊字符结尾(可能取决于编号)
  • A 函数 (ASCII) 可以正常工作
  • 最佳答案

    此代码显示如何从 Windows API 调用 *W 函数。这可能也适用于您的图书馆:

    use NativeCall;

    constant WCHAR = uint16;
    constant INT = int32;
    constant UINT = uint32;
    constant HANDLE = Pointer[void];
    constant LPWCTSTR = CArray[WCHAR];
    constant MB_ICONEXCLAMATION = 0x00000030;

    sub MessageBoxW( HANDLE, LPWCTSTR, LPWCTSTR, UINT ) is native('user32') returns INT { * };

    MessageBoxW( my $handle, to-c-str("๘❤ Raku is awesome ❤๖"), to-c-str("Hellö Wαrld"), MB_ICONEXCLAMATION );

    sub to-c-str( Str $str ) returns CArray[WCHAR]
    {
    my @str := CArray[WCHAR].new;
    for ( $str.comb ).kv -> $i, $char { @str[$i] = $char.ord; }
    @str[ $str.chars ] = 0;
    @str;
    }

    关于raku - 如何使用 NativeCall 从 Perl 6 中正确使用 libXL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58448862/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com