如何使用 NativeCall 正确使用 Perl 6 中的 libXL?



我尝试将Perl 6(最新版本(中的libXL与NativeCall一起使用。

我无法让 utf-8 正确保存创建的 xlsx 文件。

似乎只有CArray[uint16]工作,Str 也没有编码('utf8'(,也没有CArray[uint8]

最好的结果是保存工作簿,工作表名称和文本;但通常它们以特殊符号结尾。即使设置密钥也确实"经常"有效。

我的猜测是需要 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 代码结束
  • 有时,文件名以特殊字符结尾(可能取决于 Nr.(
  • 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;
}

相关内容

  • 没有找到相关文章

最新更新