[{"data":1,"prerenderedAt":1731},["ShallowReactive",2],{"navigation":3,"\u002Fblog\u002Fdart-ffi-native-bridge":46,"\u002Fblog\u002Fdart-ffi-native-bridge-surround":1726},[4],{"title":5,"path":6,"stem":7,"children":8,"page":45},"Blog","\u002Fblog","blog",[9,13,17,21,25,29,33,37,41],{"title":10,"path":11,"stem":12},"Audio Augmentation Techniques for Deep Learning","\u002Fblog\u002Faudio-augmentation","blog\u002Faudio-augmentation",{"title":14,"path":15,"stem":16},"Speed Up Whisper with CTranslate2","\u002Fblog\u002Fc-translate","blog\u002Fc-translate",{"title":18,"path":19,"stem":20},"Calling C++ and Go from Dart using FFI","\u002Fblog\u002Fdart-ffi-native-bridge","blog\u002Fdart-ffi-native-bridge",{"title":22,"path":23,"stem":24},"Russey Keo High School Memories","\u002Fblog\u002Fmemory","blog\u002Fmemory",{"title":26,"path":27,"stem":28},"My Dev Setup: Same Keys Everywhere","\u002Fblog\u002Fmy-dev-setup","blog\u002Fmy-dev-setup",{"title":30,"path":31,"stem":32},"Data Extraction with LangChain and Ollama Locally","\u002Fblog\u002Fpydantic-llm","blog\u002Fpydantic-llm",{"title":34,"path":35,"stem":36},"7-Segment LED Display with Proteus Simulation","\u002Fblog\u002Fseven-segment","blog\u002Fseven-segment",{"title":38,"path":39,"stem":40},"Understanding JWT Refresh Token Rotation & Revocation","\u002Fblog\u002Funderstand-refresh-token","blog\u002Funderstand-refresh-token",{"title":42,"path":43,"stem":44},"Khmer Speech Recognition","\u002Fblog\u002Fwhisper","blog\u002Fwhisper",false,{"id":47,"title":18,"author":48,"body":52,"date":1716,"description":1717,"extension":1718,"image":1719,"meta":1720,"minRead":150,"navigation":146,"path":19,"seo":1724,"stem":20,"__hash__":1725},"blog\u002Fblog\u002Fdart-ffi-native-bridge.md",{"name":49,"avatar":50},"Phanith LIM",{"src":51,"alt":49},"\u002Fmyprofile.jpg",{"type":53,"value":54,"toc":1698},"minimark",[55,71,74,77,82,90,94,105,230,233,271,275,290,565,568,609,613,620,847,850,898,901,916,919,923,926,931,1063,1067,1143,1149,1151,1155,1159,1290,1294,1400,1403,1492,1495,1583,1586,1672,1674,1678,1687,1694],[56,57,58,62,63,66,67,70],"p",{},[59,60,61],"code",{},"dart:ffi"," lets Dart call into a shared library (",[59,64,65],{},".so"," or ",[59,68,69],{},".dylib",") directly. No platform channels, no plugin, no Flutter needed.",[56,72,73],{},"That is worth having when the code you want already exists in C or C++ and you would rather bind to it than port it, or when a hot loop is faster in a compiled language than in Dart. The cost is that you now have a build step per platform and a pointer or two to look after.",[56,75,76],{},"I wired up C++ and Go this way and worked out which other languages can join in. Both are below.",[78,79,81],"h2",{"id":80},"the-one-rule","The one rule",[56,83,84,85,89],{},"Dart can only call functions that expose a ",[86,87,88],"strong",{},"C ABI",": a plain C-compatible symbol with no name mangling. Every language reaches that differently, but the Dart side never changes: open the library, declare the types, look up the function.",[78,91,93],{"id":92},"c","C++",[56,95,96,97,100,101,104],{},"C++ mangles function names, so ",[59,98,99],{},"add"," becomes something unrecognisable. ",[59,102,103],{},"extern \"C\""," turns that off.",[106,107,112],"pre",{"className":108,"code":109,"language":110,"meta":111,"style":111},"language-cpp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F native\u002Fcpp\u002Fmylib.cpp\n#include \u003Ccstdint>\n\nextern \"C\" {\n  int32_t add(int32_t a, int32_t b) {\n    return a + b;\n  }\n}\n","cpp","",[59,113,114,123,141,148,167,201,218,224],{"__ignoreMap":111},[115,116,119],"span",{"class":117,"line":118},"line",1,[115,120,122],{"class":121},"sHwdD","\u002F\u002F native\u002Fcpp\u002Fmylib.cpp\n",[115,124,126,130,134,138],{"class":117,"line":125},2,[115,127,129],{"class":128},"s7zQu","#include",[115,131,133],{"class":132},"sMK4o"," \u003C",[115,135,137],{"class":136},"sfazB","cstdint",[115,139,140],{"class":132},">\n",[115,142,144],{"class":117,"line":143},3,[115,145,147],{"emptyLinePlaceholder":146},true,"\n",[115,149,151,155,158,161,164],{"class":117,"line":150},4,[115,152,154],{"class":153},"spNyl","extern",[115,156,157],{"class":132}," \"",[115,159,160],{"class":136},"C",[115,162,163],{"class":132},"\"",[115,165,166],{"class":132}," {\n",[115,168,170,173,177,180,183,187,190,193,196,199],{"class":117,"line":169},5,[115,171,172],{"class":153},"  int32_t",[115,174,176],{"class":175},"s2Zo4"," add",[115,178,179],{"class":132},"(",[115,181,182],{"class":153},"int32_t",[115,184,186],{"class":185},"sHdIc"," a",[115,188,189],{"class":132},",",[115,191,192],{"class":153}," int32_t",[115,194,195],{"class":185}," b",[115,197,198],{"class":132},")",[115,200,166],{"class":132},[115,202,204,207,210,213,215],{"class":117,"line":203},6,[115,205,206],{"class":128},"    return",[115,208,186],{"class":209},"sTEyZ",[115,211,212],{"class":132}," +",[115,214,195],{"class":209},[115,216,217],{"class":132},";\n",[115,219,221],{"class":117,"line":220},7,[115,222,223],{"class":132},"  }\n",[115,225,227],{"class":117,"line":226},8,[115,228,229],{"class":132},"}\n",[56,231,232],{},"Build it with CMake:",[106,234,238],{"className":235,"code":236,"language":237,"meta":111,"style":111},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","cmake -S native\u002Fcpp -B native\u002Fcpp\u002Fbuild -DCMAKE_BUILD_TYPE=Release\ncmake --build native\u002Fcpp\u002Fbuild\n","bash",[59,239,240,261],{"__ignoreMap":111},[115,241,242,246,249,252,255,258],{"class":117,"line":118},[115,243,245],{"class":244},"sBMFI","cmake",[115,247,248],{"class":136}," -S",[115,250,251],{"class":136}," native\u002Fcpp",[115,253,254],{"class":136}," -B",[115,256,257],{"class":136}," native\u002Fcpp\u002Fbuild",[115,259,260],{"class":136}," -DCMAKE_BUILD_TYPE=Release\n",[115,262,263,265,268],{"class":117,"line":125},[115,264,245],{"class":244},[115,266,267],{"class":136}," --build",[115,269,270],{"class":136}," native\u002Fcpp\u002Fbuild\n",[78,272,274],{"id":273},"go","Go",[56,276,277,278,281,282,285,286,289],{},"Go exports through CGo. Two details will bite you if you miss them: the file needs ",[59,279,280],{},"package main"," with an empty ",[59,283,284],{},"func main()",", and ",[59,287,288],{},"\u002F\u002Fexport"," must sit on the line directly above the function, with no blank line between.",[106,291,294],{"className":292,"code":293,"language":273,"meta":111,"style":111},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F native\u002Fgo\u002Fmylib.go\npackage main\n\nimport \"C\"\n\n\u002F\u002Fexport multiply\nfunc multiply(a, b int32) int32 { return a * b }\n\n\u002F\u002Fexport fibonacci\nfunc fibonacci(n int32) int64 {\n    if n \u003C= 1 { return int64(n) }\n    a, b := int64(0), int64(1)\n    for i := int32(2); i \u003C= n; i++ { a, b = b, a+b }\n    return b\n}\n\nfunc main() {}\n",[59,295,296,301,309,313,325,329,334,375,379,385,407,438,471,533,541,546,551],{"__ignoreMap":111},[115,297,298],{"class":117,"line":118},[115,299,300],{"class":121},"\u002F\u002F native\u002Fgo\u002Fmylib.go\n",[115,302,303,306],{"class":117,"line":125},[115,304,305],{"class":132},"package",[115,307,308],{"class":244}," main\n",[115,310,311],{"class":117,"line":143},[115,312,147],{"emptyLinePlaceholder":146},[115,314,315,318,320,322],{"class":117,"line":150},[115,316,317],{"class":128},"import",[115,319,157],{"class":132},[115,321,160],{"class":244},[115,323,324],{"class":132},"\"\n",[115,326,327],{"class":117,"line":169},[115,328,147],{"emptyLinePlaceholder":146},[115,330,331],{"class":117,"line":203},[115,332,333],{"class":121},"\u002F\u002Fexport multiply\n",[115,335,336,339,342,344,347,349,351,354,356,358,361,364,367,370,373],{"class":117,"line":220},[115,337,338],{"class":132},"func",[115,340,341],{"class":175}," multiply",[115,343,179],{"class":132},[115,345,346],{"class":185},"a",[115,348,189],{"class":132},[115,350,195],{"class":185},[115,352,353],{"class":153}," int32",[115,355,198],{"class":132},[115,357,353],{"class":153},[115,359,360],{"class":132}," {",[115,362,363],{"class":128}," return",[115,365,366],{"class":209}," a ",[115,368,369],{"class":132},"*",[115,371,372],{"class":209}," b ",[115,374,229],{"class":132},[115,376,377],{"class":117,"line":226},[115,378,147],{"emptyLinePlaceholder":146},[115,380,382],{"class":117,"line":381},9,[115,383,384],{"class":121},"\u002F\u002Fexport fibonacci\n",[115,386,388,390,393,395,398,400,402,405],{"class":117,"line":387},10,[115,389,338],{"class":132},[115,391,392],{"class":175}," fibonacci",[115,394,179],{"class":132},[115,396,397],{"class":185},"n",[115,399,353],{"class":153},[115,401,198],{"class":132},[115,403,404],{"class":153}," int64",[115,406,166],{"class":132},[115,408,410,413,416,419,423,425,427,429,431,433,435],{"class":117,"line":409},11,[115,411,412],{"class":128},"    if",[115,414,415],{"class":209}," n ",[115,417,418],{"class":132},"\u003C=",[115,420,422],{"class":421},"sbssI"," 1",[115,424,360],{"class":132},[115,426,363],{"class":128},[115,428,404],{"class":153},[115,430,179],{"class":132},[115,432,397],{"class":209},[115,434,198],{"class":132},[115,436,437],{"class":132}," }\n",[115,439,441,444,446,448,451,453,455,458,461,463,465,468],{"class":117,"line":440},12,[115,442,443],{"class":209},"    a",[115,445,189],{"class":132},[115,447,372],{"class":209},[115,449,450],{"class":132},":=",[115,452,404],{"class":153},[115,454,179],{"class":132},[115,456,457],{"class":421},"0",[115,459,460],{"class":132},"),",[115,462,404],{"class":153},[115,464,179],{"class":132},[115,466,467],{"class":421},"1",[115,469,470],{"class":132},")\n",[115,472,474,477,480,482,484,486,489,492,494,496,499,502,505,508,510,512,514,516,519,521,523,525,528,531],{"class":117,"line":473},13,[115,475,476],{"class":128},"    for",[115,478,479],{"class":209}," i ",[115,481,450],{"class":132},[115,483,353],{"class":153},[115,485,179],{"class":132},[115,487,488],{"class":421},"2",[115,490,491],{"class":132},");",[115,493,479],{"class":209},[115,495,418],{"class":132},[115,497,498],{"class":209}," n",[115,500,501],{"class":132},";",[115,503,504],{"class":209}," i",[115,506,507],{"class":132},"++",[115,509,360],{"class":132},[115,511,186],{"class":209},[115,513,189],{"class":132},[115,515,372],{"class":209},[115,517,518],{"class":132},"=",[115,520,195],{"class":209},[115,522,189],{"class":132},[115,524,186],{"class":209},[115,526,527],{"class":132},"+",[115,529,530],{"class":209},"b ",[115,532,229],{"class":132},[115,534,536,538],{"class":117,"line":535},14,[115,537,206],{"class":128},[115,539,540],{"class":209}," b\n",[115,542,544],{"class":117,"line":543},15,[115,545,229],{"class":132},[115,547,549],{"class":117,"line":548},16,[115,550,147],{"emptyLinePlaceholder":146},[115,552,554,556,559,562],{"class":117,"line":553},17,[115,555,338],{"class":132},[115,557,558],{"class":175}," main",[115,560,561],{"class":132},"()",[115,563,564],{"class":132}," {}\n",[56,566,567],{},"Build:",[106,569,571],{"className":235,"code":570,"language":237,"meta":111,"style":111},"cd native\u002Fgo && CGO_ENABLED=1 go build -o ..\u002Flibs\u002Flibgolib.so -buildmode=c-shared .\n",[59,572,573],{"__ignoreMap":111},[115,574,575,578,581,584,587,589,591,594,597,600,603,606],{"class":117,"line":118},[115,576,577],{"class":175},"cd",[115,579,580],{"class":136}," native\u002Fgo",[115,582,583],{"class":132}," &&",[115,585,586],{"class":209}," CGO_ENABLED",[115,588,518],{"class":132},[115,590,467],{"class":136},[115,592,593],{"class":244}," go",[115,595,596],{"class":136}," build",[115,598,599],{"class":136}," -o",[115,601,602],{"class":136}," ..\u002Flibs\u002Flibgolib.so",[115,604,605],{"class":136}," -buildmode=c-shared",[115,607,608],{"class":136}," .\n",[78,610,612],{"id":611},"the-dart-side","The Dart side",[56,614,615,616,619],{},"This part is the same no matter which language produced the library. Declare the native signature, declare the Dart signature, then ",[59,617,618],{},"lookupFunction",".",[106,621,625],{"className":622,"code":623,"language":624,"meta":111,"style":111},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F lib\u002Fsrc\u002Fgo_bindings.dart\nimport 'dart:ffi';\nimport 'package:path\u002Fpath.dart' as p;\n\ntypedef _FibonacciNative = Int64 Function(Int32 n);\ntypedef FibonacciDart = int Function(int n);\n\nclass GoLib {\n  final DynamicLibrary _lib;\n  late final FibonacciDart fibonacci;\n\n  GoLib(String libsDir)\n      : _lib = DynamicLibrary.open(p.join(libsDir, 'libgolib.so')) {\n    fibonacci = _lib.lookupFunction\u003C_FibonacciNative, FibonacciDart>('fibonacci');\n  }\n}\n","dart",[59,626,627,632,641,656,660,687,710,714,724,737,751,755,768,804,839,843],{"__ignoreMap":111},[115,628,629],{"class":117,"line":118},[115,630,631],{"class":121},"\u002F\u002F lib\u002Fsrc\u002Fgo_bindings.dart\n",[115,633,634,636,639],{"class":117,"line":125},[115,635,317],{"class":421},[115,637,638],{"class":136}," 'dart:ffi'",[115,640,217],{"class":132},[115,642,643,645,648,651,654],{"class":117,"line":143},[115,644,317],{"class":421},[115,646,647],{"class":136}," 'package:path\u002Fpath.dart'",[115,649,650],{"class":421}," as",[115,652,653],{"class":209}," p",[115,655,217],{"class":132},[115,657,658],{"class":117,"line":150},[115,659,147],{"emptyLinePlaceholder":146},[115,661,662,665,668,671,674,677,679,682,685],{"class":117,"line":169},[115,663,664],{"class":132},"typedef",[115,666,667],{"class":244}," _FibonacciNative",[115,669,670],{"class":132}," =",[115,672,673],{"class":244}," Int64",[115,675,676],{"class":244}," Function",[115,678,179],{"class":209},[115,680,681],{"class":244},"Int32",[115,683,684],{"class":209}," n)",[115,686,217],{"class":132},[115,688,689,691,694,696,699,701,703,706,708],{"class":117,"line":203},[115,690,664],{"class":132},[115,692,693],{"class":244}," FibonacciDart",[115,695,670],{"class":132},[115,697,698],{"class":244}," int",[115,700,676],{"class":244},[115,702,179],{"class":209},[115,704,705],{"class":244},"int",[115,707,684],{"class":209},[115,709,217],{"class":132},[115,711,712],{"class":117,"line":220},[115,713,147],{"emptyLinePlaceholder":146},[115,715,716,719,722],{"class":117,"line":226},[115,717,718],{"class":132},"class",[115,720,721],{"class":244}," GoLib",[115,723,166],{"class":209},[115,725,726,729,732,735],{"class":117,"line":381},[115,727,728],{"class":153},"  final",[115,730,731],{"class":244}," DynamicLibrary",[115,733,734],{"class":209}," _lib",[115,736,217],{"class":132},[115,738,739,742,745,747,749],{"class":117,"line":387},[115,740,741],{"class":153},"  late",[115,743,744],{"class":153}," final",[115,746,693],{"class":244},[115,748,392],{"class":209},[115,750,217],{"class":132},[115,752,753],{"class":117,"line":409},[115,754,147],{"emptyLinePlaceholder":146},[115,756,757,760,762,765],{"class":117,"line":440},[115,758,759],{"class":244},"  GoLib",[115,761,179],{"class":209},[115,763,764],{"class":244},"String",[115,766,767],{"class":209}," libsDir)\n",[115,769,770,773,776,778,780,782,785,788,790,793,796,798,801],{"class":117,"line":473},[115,771,772],{"class":132},"      :",[115,774,775],{"class":209}," _lib ",[115,777,518],{"class":132},[115,779,731],{"class":244},[115,781,619],{"class":132},[115,783,784],{"class":175},"open",[115,786,787],{"class":209},"(p",[115,789,619],{"class":132},[115,791,792],{"class":175},"join",[115,794,795],{"class":209},"(libsDir",[115,797,189],{"class":132},[115,799,800],{"class":136}," 'libgolib.so'",[115,802,803],{"class":209},")) {\n",[115,805,806,809,811,813,815,817,820,823,826,829,832,835,837],{"class":117,"line":535},[115,807,808],{"class":209},"    fibonacci ",[115,810,518],{"class":132},[115,812,734],{"class":209},[115,814,619],{"class":132},[115,816,618],{"class":175},[115,818,819],{"class":209},"\u003C",[115,821,822],{"class":244},"_FibonacciNative",[115,824,825],{"class":209},", ",[115,827,828],{"class":244},"FibonacciDart",[115,830,831],{"class":209},">(",[115,833,834],{"class":136},"'fibonacci'",[115,836,198],{"class":209},[115,838,217],{"class":132},[115,840,841],{"class":117,"line":543},[115,842,223],{"class":209},[115,844,845],{"class":117,"line":548},[115,846,229],{"class":209},[56,848,849],{},"Then call it like ordinary Dart:",[106,851,853],{"className":622,"code":852,"language":624,"meta":111,"style":111},"final go = GoLib(libsDir);\nprint(go.fibonacci(10)); \u002F\u002F 55\n",[59,854,855,872],{"__ignoreMap":111},[115,856,857,860,863,865,867,870],{"class":117,"line":118},[115,858,859],{"class":153},"final",[115,861,862],{"class":209}," go ",[115,864,518],{"class":132},[115,866,721],{"class":244},[115,868,869],{"class":209},"(libsDir)",[115,871,217],{"class":132},[115,873,874,877,880,882,885,887,890,893,895],{"class":117,"line":125},[115,875,876],{"class":175},"print",[115,878,879],{"class":209},"(go",[115,881,619],{"class":132},[115,883,884],{"class":175},"fibonacci",[115,886,179],{"class":209},[115,888,889],{"class":421},"10",[115,891,892],{"class":209},"))",[115,894,501],{"class":132},[115,896,897],{"class":121}," \u002F\u002F 55\n",[56,899,900],{},"Numbers are the easy case. They copy across on their own, and nothing needs cleaning up afterwards.",[56,902,903,904,907,908,911,912,915],{},"Strings do not. A ",[59,905,906],{},"Pointer\u003CUtf8>"," is memory you asked for, so you convert with ",[59,909,910],{},"toNativeUtf8()",", pass the pointer, read the reply back with ",[59,913,914],{},"toDartString()",", and free what you allocated. Forget the free and you have a leak that no garbage collector will find for you.",[917,918],"hr",{},[78,920,922],{"id":921},"which-languages-work","Which languages work",[56,924,925],{},"Anything that compiles to a shared library with C-compatible symbols.",[927,928,930],"h3",{"id":929},"works","Works",[932,933,934,947],"table",{},[935,936,937],"thead",{},[938,939,940,944],"tr",{},[941,942,943],"th",{},"Language",[941,945,946],{},"Export mechanism",[948,949,950,958,968,981,994,1005,1016,1027,1038,1049],"tbody",{},[938,951,952,955],{},[953,954,160],"td",{},[953,956,957],{},"Native, no wrapper needed",[938,959,960,962],{},[953,961,93],{},[953,963,964,967],{},[59,965,966],{},"extern \"C\" { ... }"," block",[938,969,970,972],{},[953,971,274],{},[953,973,974,975,977,978],{},"CGo ",[59,976,288],{}," + ",[59,979,980],{},"-buildmode=c-shared",[938,982,983,986],{},[953,984,985],{},"Rust",[953,987,988,977,991],{},[59,989,990],{},"#[no_mangle] extern \"C\" fn",[59,992,993],{},"crate-type = [\"cdylib\"]",[938,995,996,999],{},[953,997,998],{},"Zig",[953,1000,1001,1004],{},[59,1002,1003],{},"export fn"," + compile as shared library",[938,1006,1007,1010],{},[953,1008,1009],{},"Nim",[953,1011,1012,1015],{},[59,1013,1014],{},"{.exportc, dynlib.}"," pragma",[938,1017,1018,1021],{},[953,1019,1020],{},"D",[953,1022,1023,1026],{},[59,1024,1025],{},"extern(C)"," linkage",[938,1028,1029,1032],{},[953,1030,1031],{},"Kotlin\u002FNative",[953,1033,1034,1037],{},[59,1035,1036],{},"@CName"," annotation (not Kotlin\u002FJVM)",[938,1039,1040,1043],{},[953,1041,1042],{},"Swift",[953,1044,1045,1048],{},[59,1046,1047],{},"@_cdecl(\"name\")"," on a free function",[938,1050,1051,1054],{},[953,1052,1053],{},"Fortran",[953,1055,1056,977,1059,1062],{},[59,1057,1058],{},"ISO_C_BINDING",[59,1060,1061],{},"bind(C)"," attribute",[927,1064,1066],{"id":1065},"does-not-work","Does not work",[932,1068,1069,1078],{},[935,1070,1071],{},[938,1072,1073,1075],{},[941,1074,943],{},[941,1076,1077],{},"Reason",[948,1079,1080,1088,1096,1104,1112,1120,1128,1136],{},[938,1081,1082,1085],{},[953,1083,1084],{},"Python",[953,1086,1087],{},"No C ABI export, would need embedding CPython",[938,1089,1090,1093],{},[953,1091,1092],{},"Java",[953,1094,1095],{},"JVM bytecode only; JNI goes the other direction",[938,1097,1098,1101],{},[953,1099,1100],{},"Kotlin (JVM)",[953,1102,1103],{},"Runs on the JVM, no C ABI",[938,1105,1106,1109],{},[953,1107,1108],{},"Scala",[953,1110,1111],{},"JVM, no C ABI",[938,1113,1114,1117],{},[953,1115,1116],{},"C# \u002F .NET",[953,1118,1119],{},"CLR managed runtime, no native C ABI export",[938,1121,1122,1125],{},[953,1123,1124],{},"JavaScript \u002F TypeScript",[953,1126,1127],{},"Runs in a JS engine, no C ABI",[938,1129,1130,1133],{},[953,1131,1132],{},"Ruby",[953,1134,1135],{},"Interpreter-based, no C ABI export",[938,1137,1138,1141],{},[953,1139,1140],{},"PHP",[953,1142,1135],{},[56,1144,1145,1146,1148],{},"The pattern behind both tables: if the language can produce a ",[59,1147,65],{}," with plain C symbol names, Dart FFI can call it. If it needs its own runtime to be alive first, it cannot.",[917,1150],{},[78,1152,1154],{"id":1153},"type-mappings","Type mappings",[927,1156,1158],{"id":1157},"c-and-c","C and C++",[932,1160,1161,1171],{},[935,1162,1163],{},[938,1164,1165,1168],{},[941,1166,1167],{},"Dart FFI type",[941,1169,1170],{},"C \u002F C++ type",[948,1172,1173,1185,1197,1207,1219,1231,1243,1255,1267,1278],{},[938,1174,1175,1180],{},[953,1176,1177],{},[59,1178,1179],{},"Int8",[953,1181,1182],{},[59,1183,1184],{},"int8_t",[938,1186,1187,1192],{},[953,1188,1189],{},[59,1190,1191],{},"Int16",[953,1193,1194],{},[59,1195,1196],{},"int16_t",[938,1198,1199,1203],{},[953,1200,1201],{},[59,1202,681],{},[953,1204,1205],{},[59,1206,182],{},[938,1208,1209,1214],{},[953,1210,1211],{},[59,1212,1213],{},"Int64",[953,1215,1216],{},[59,1217,1218],{},"int64_t",[938,1220,1221,1226],{},[953,1222,1223],{},[59,1224,1225],{},"Float",[953,1227,1228],{},[59,1229,1230],{},"float",[938,1232,1233,1238],{},[953,1234,1235],{},[59,1236,1237],{},"Double",[953,1239,1240],{},[59,1241,1242],{},"double",[938,1244,1245,1250],{},[953,1246,1247],{},[59,1248,1249],{},"Bool",[953,1251,1252],{},[59,1253,1254],{},"bool",[938,1256,1257,1262],{},[953,1258,1259],{},[59,1260,1261],{},"Void",[953,1263,1264],{},[59,1265,1266],{},"void",[938,1268,1269,1273],{},[953,1270,1271],{},[59,1272,906],{},[953,1274,1275],{},[59,1276,1277],{},"char*",[938,1279,1280,1285],{},[953,1281,1282],{},[59,1283,1284],{},"Pointer\u003CT>",[953,1286,1287],{},[59,1288,1289],{},"T*",[927,1291,1293],{"id":1292},"go-via-cgo","Go (via CGo)",[932,1295,1296,1305],{},[935,1297,1298],{},[938,1299,1300,1302],{},[941,1301,1167],{},[941,1303,1304],{},"Go \u002F CGo type",[948,1306,1307,1322,1336,1350,1364,1377,1388],{},[938,1308,1309,1313],{},[953,1310,1311],{},[59,1312,681],{},[953,1314,1315,1318,1319],{},[59,1316,1317],{},"int32"," \u002F ",[59,1320,1321],{},"C.int",[938,1323,1324,1328],{},[953,1325,1326],{},[59,1327,1213],{},[953,1329,1330,1318,1333],{},[59,1331,1332],{},"int64",[59,1334,1335],{},"C.longlong",[938,1337,1338,1342],{},[953,1339,1340],{},[59,1341,1225],{},[953,1343,1344,1318,1347],{},[59,1345,1346],{},"float32",[59,1348,1349],{},"C.float",[938,1351,1352,1356],{},[953,1353,1354],{},[59,1355,1237],{},[953,1357,1358,1318,1361],{},[59,1359,1360],{},"float64",[59,1362,1363],{},"C.double",[938,1365,1366,1370],{},[953,1367,1368],{},[59,1369,1249],{},[953,1371,1372,1318,1374,1376],{},[59,1373,1254],{},[59,1375,1321],{}," (0\u002F1)",[938,1378,1379,1383],{},[953,1380,1381],{},[59,1382,906],{},[953,1384,1385],{},[59,1386,1387],{},"*C.char",[938,1389,1390,1395],{},[953,1391,1392],{},[59,1393,1394],{},"Pointer\u003CInt32>",[953,1396,1397],{},[59,1398,1399],{},"*C.int",[927,1401,985],{"id":1402},"rust",[932,1404,1405,1414],{},[935,1406,1407],{},[938,1408,1409,1411],{},[941,1410,1167],{},[941,1412,1413],{},"Rust type",[948,1415,1416,1427,1438,1449,1460,1470,1481],{},[938,1417,1418,1422],{},[953,1419,1420],{},[59,1421,681],{},[953,1423,1424],{},[59,1425,1426],{},"i32",[938,1428,1429,1433],{},[953,1430,1431],{},[59,1432,1213],{},[953,1434,1435],{},[59,1436,1437],{},"i64",[938,1439,1440,1444],{},[953,1441,1442],{},[59,1443,1225],{},[953,1445,1446],{},[59,1447,1448],{},"f32",[938,1450,1451,1455],{},[953,1452,1453],{},[59,1454,1237],{},[953,1456,1457],{},[59,1458,1459],{},"f64",[938,1461,1462,1466],{},[953,1463,1464],{},[59,1465,1249],{},[953,1467,1468],{},[59,1469,1254],{},[938,1471,1472,1476],{},[953,1473,1474],{},[59,1475,906],{},[953,1477,1478],{},[59,1479,1480],{},"*const c_char",[938,1482,1483,1487],{},[953,1484,1485],{},[59,1486,1284],{},[953,1488,1489],{},[59,1490,1491],{},"*mut T",[927,1493,1031],{"id":1494},"kotlinnative",[932,1496,1497,1506],{},[935,1498,1499],{},[938,1500,1501,1503],{},[941,1502,1167],{},[941,1504,1505],{},"Kotlin type",[948,1507,1508,1519,1530,1540,1550,1561,1572],{},[938,1509,1510,1514],{},[953,1511,1512],{},[59,1513,681],{},[953,1515,1516],{},[59,1517,1518],{},"Int",[938,1520,1521,1525],{},[953,1522,1523],{},[59,1524,1213],{},[953,1526,1527],{},[59,1528,1529],{},"Long",[938,1531,1532,1536],{},[953,1533,1534],{},[59,1535,1225],{},[953,1537,1538],{},[59,1539,1225],{},[938,1541,1542,1546],{},[953,1543,1544],{},[59,1545,1237],{},[953,1547,1548],{},[59,1549,1237],{},[938,1551,1552,1556],{},[953,1553,1554],{},[59,1555,1249],{},[953,1557,1558],{},[59,1559,1560],{},"Boolean",[938,1562,1563,1567],{},[953,1564,1565],{},[59,1566,906],{},[953,1568,1569],{},[59,1570,1571],{},"CPointer\u003CByteVar>?",[938,1573,1574,1578],{},[953,1575,1576],{},[59,1577,1394],{},[953,1579,1580],{},[59,1581,1582],{},"CPointer\u003CIntVar>?",[927,1584,1042],{"id":1585},"swift",[932,1587,1588,1597],{},[935,1589,1590],{},[938,1591,1592,1594],{},[941,1593,1167],{},[941,1595,1596],{},"Swift type",[948,1598,1599,1609,1619,1629,1639,1649,1660],{},[938,1600,1601,1605],{},[953,1602,1603],{},[59,1604,681],{},[953,1606,1607],{},[59,1608,681],{},[938,1610,1611,1615],{},[953,1612,1613],{},[59,1614,1213],{},[953,1616,1617],{},[59,1618,1213],{},[938,1620,1621,1625],{},[953,1622,1623],{},[59,1624,1225],{},[953,1626,1627],{},[59,1628,1225],{},[938,1630,1631,1635],{},[953,1632,1633],{},[59,1634,1237],{},[953,1636,1637],{},[59,1638,1237],{},[938,1640,1641,1645],{},[953,1642,1643],{},[59,1644,1249],{},[953,1646,1647],{},[59,1648,1249],{},[938,1650,1651,1655],{},[953,1652,1653],{},[59,1654,906],{},[953,1656,1657],{},[59,1658,1659],{},"UnsafePointer\u003CCChar>?",[938,1661,1662,1666],{},[953,1663,1664],{},[59,1665,906],{},[953,1667,1668,1671],{},[59,1669,1670],{},"UnsafeMutablePointer\u003CCChar>?"," (out)",[917,1673],{},[78,1675,1677],{"id":1676},"source","Source",[56,1679,1680,1681],{},"Source code: ",[346,1682,1686],{"href":1683,"rel":1684},"https:\u002F\u002Fgithub.com\u002Fphanithlim\u002Fdart-native",[1685],"nofollow","phanithlim\u002Fdart-native",[56,1688,1689,1690,1693],{},"Everything lives under ",[59,1691,1692],{},"native\u002F",", one directory per language, each with its own README and build steps. Clone it, build one of the libraries, and the Dart side will call straight into it.",[1695,1696,1697],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":111,"searchDepth":125,"depth":125,"links":1699},[1700,1701,1702,1703,1704,1708,1715],{"id":80,"depth":125,"text":81},{"id":92,"depth":125,"text":93},{"id":273,"depth":125,"text":274},{"id":611,"depth":125,"text":612},{"id":921,"depth":125,"text":922,"children":1705},[1706,1707],{"id":929,"depth":143,"text":930},{"id":1065,"depth":143,"text":1066},{"id":1153,"depth":125,"text":1154,"children":1709},[1710,1711,1712,1713,1714],{"id":1157,"depth":143,"text":1158},{"id":1292,"depth":143,"text":1293},{"id":1402,"depth":143,"text":985},{"id":1494,"depth":143,"text":1031},{"id":1585,"depth":143,"text":1042},{"id":1676,"depth":125,"text":1677},"2026-06-02","Calling native libraries from Dart with dart:ffi, and which languages work.","md","\u002Fblog\u002Fdart-ffi-native-bridge\u002Fcover.jpg",{"tags":1721},[1722,1723],"Dart","FFI",{"title":18,"description":1717},"ZhFB4P4xj5eoA7PeGlInQmuG8DbLq9e34CcYib-16dc",[1727,1729],{"title":14,"path":15,"stem":16,"description":1728,"children":-1},"Converting Whisper with CTranslate2 so it runs faster and lighter.",{"title":22,"path":23,"stem":24,"description":1730,"children":-1},"A video of my high school years, made after the BACII exam.",1791981008543]