99.9RMB 悬赏一技术支持 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
phpIsNumberOne

99.9RMB 悬赏一技术支持

  •  
  •   phpIsNumberOne Feb 26, 2021 7760 views
    This topic created in 1886 days ago, the information mentioned may be changed or developed.
    概述:

    使用 C 打包为 Android 的 C-shar(so)动态链库,然后使用 Fltter 的 ffi 调用。现在我实现了函数为 int 类型的相互调用,但是 string(*char)始终有问题。

    要求:

    将 C 程序打包为 so 动态链库,并能在 Flutter 项目上正常使用,仅 Android 即可,使用 CMake ; C 程序:

    #include <stdio.h> #include <stdlib.h> int Hello(){ return 233; } char *World(){ char *r = "1234"; return r; } char *Test(char *str) { return str; } 
    说明:
    • 单纯使用 Dart 调用动态链库是完全没问题的,包括函数返回类型是*char,这是在 Windows 上测试的。
    • 将动态链库使用到 Flutter 上时,只有返回为 int 等数值类型的才没问题,调用返回*char 类型的函数时会闪退;这是你需要为我解决的。
    • 先到先得,可以加点价。
    相关资料:
    • C 交叉编译为 Android C-share 库

    • Dart ffi 调用动态链接库官方 Demo

    • 我自己写的 ffi 类,可供参考:链接: https://pan.baidu.com/s/1z-ooHzgkbM2SkzWrkJs4eA 提取码: 9awt

    • 在 Flutte上使用 C

    • 我打包的动态链库,如果相信没问题可以直接用:链接: https://pan.baidu.com/s/16lZ8NwUexXJ3rpFcCxZwLw 提取码: c8s7

      打包命令: D:\Desktop\test>E:\android-ndk-r22-windows-x86_64\android-ndk-r22\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android24-clang -shared -o mylib.so -Xlinker -sOname=mylib.so -lm mylib.c D:\Desktop\test>E:\android-ndk-r22-windows-x86_64\android-ndk-r22\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android-nm.exe ./mylib.so 00000000000014f4 t __atexit_handler_wrapper U __cxa_atexit U __cxa_finalize 00000000000025b0 d __dso_handle 00000000000025b0 d __dso_handle_const 00000000000014ec t __emutls_unregister_key 00000000000004dc r __FRAME_END__ 00000000000014e0 t __on_dlclose 00000000000014f0 t __on_dlclose_late U __register_atfork 00000000000025c8 d _DYNAMIC 0000000000001500 t atexit 0000000000001528 T Hello 0000000000000290 r ndk_build_number 0000000000000250 r ndk_version 0000000000000238 r note_android_ident 000000000000024c r note_data 00000000000002d0 r note_end 0000000000000244 r note_name 000000000000151c t pthread_atfork 000000000000154c T Test 0000000000001530 T World 
    40 replies    2021-02-27 17:55:56 +08:00
    kosgug
        1
    kosgug  
       Feb 26, 2021
    建议把悬赏金额调低
    F281M6Dh8DXpD1g2
        2
    F281M6Dh8DXpD1g2  
       Feb 26, 2021
    单纯的提问都比你这 99.9 好
    20015jjw
        3
    20015jjw  
       Feb 26, 2021 via Android   1
    这就跟求包养
    一个月只要两包泡面一样...
    pekki
        4
    pekki  
       Feb 26, 2021
    你是不是把程序员的时薪想的太低了。。。
    youthfire
        5
    youthfire  
       Feb 26, 2021 via iPhone   4
    传说中的伤害性不大,侮辱性极强
    heyjei
        6
    heyjei  
       Feb 26, 2021   4
    一杯星巴克或者一杯瑞幸的外卖都比你这个 99.9 更有吸引力啊
    hanxiV2EX
        7
    hanxiV2EX  
       Feb 26, 2021   2
    试试这样?记得 free 它

    char *World(){
    char *tmp = "1234";
    char *r = malloc(strlen(tmp)+1);
    strcpy(r, tmp);
    return r;
    }

    void FreeWorld(char *){
    free(r)
    }
    wzb0909
        8
    wzb0909  
       Feb 26, 2021
    99 元让人看完你的字都不够啊
    hanxiV2EX
        9
    hanxiV2EX  
       Feb 26, 2021   1
    建议 @phpIsNumberOne 重新学习 C 语言吧,内存没搞清楚写出来的东西会挂的。
    danhahaha
        10
    danhahaha  
       Feb 26, 2021
    建议改成 100.99 或者 0.1K 这样看起来比较多
    vone
        11
    vone  
       Feb 26, 2021
    没八百这活干不了。
    hanssx
        12
    hanssx  
       Feb 26, 2021   3
    99.9 不少了,而且题主提问的方式挺正规的吧?
    话说我记得*和后面的之间是不是加个空格更 c ?
    mm163
        13
    mm163  
       Feb 26, 2021
    Flutter 没用过,不清楚。
    java 虚拟环境与 c 不是一个空间的,字符串处理应该使用 jni,不能直接返回指针。
    pkookp8
        14
    pkookp8  
       Feb 26, 2021 via Android
    我觉得需要开辟一块共享内存或者普通内存用来操作字符串。world 的 1234 是在字符常量区,可读不可写。test 的内存不知道哪来的,不知道可不可读写

    char*不行 int 行,显然是内存问题。但是不懂 flutter,无能为力。试试对入参或出参进行申请内存,使用后释放。或者 socket 交互
    anonydmer
        15
    anonydmer  
       Feb 26, 2021
    亲,你这样用 C 返回字符串是不行的哦,内存管理错了
    hantsy
        16
    hantsy  
       Feb 26, 2021
    9 。9 包邮
    Chenamy2017
        17
    Chenamy2017  
       Feb 26, 2021
    好好学学 C 语言吧,指针内存什么的。
    你这个 World 函数返回的指针有问题。
    phpIsNumberOne
        18
    phpIsNumberOne  
    OP
       Feb 26, 2021
    @hanxiV2EX
    @Chenamy2017
    见笑了,C 就大学学了下,后面就没深入了
    wangjunling
        19
    wangjunling  
       Feb 26, 2021
    还不如直接求帮助, 99 悬赏真是侮辱程序员这个行业呀, 理解问题, 解决问题, 至少你的来个三位数呀, 999 或许真有人接
    hanxiV2EX
        20
    hanxiV2EX  
       Feb 26, 2021
    楼主提问表述确实很清楚,有经验的一眼也就能看到问题所在。然后提供的资料也还全面,这样的提问还是值得称赞的。
    oxromantic
        21
    oxromantic  
       Feb 26, 2021   2
    楼上一群冷嘲热讽的不知道有没有认真看代码, 至少楼主的例子我用 flutter 跑了下是可以传到 flutter 端的

    楼主的例子是 literals string, 本来就不需要栈上分配内存, 直接 return 又如何?

    不知道楼主 flutter 端是怎么写的, 至少我是这样可以取到的:

    #include <stdint.h>
    #include <string.h>

    extern "C" __attribute__((visibility("default"))) __attribute__((used))
    char* native_add(int32_t x, int32_t y) {
    return "12345";
    }

    final Pointer<Utf8> Function(int x, int y) nativeAdd = nativeAddLib
    .lookup<NativeFunction<Pointer<Utf8> Function(Int32, Int32)>>(
    "native_add")
    .asFunction();

    Text('Running on: $_platformVersion ${Utf8.fromUtf8(nativeAdd(3, 3))}\n')
    Visitor233
        22
    Visitor233  
       Feb 26, 2021
    @hanxiV2EX 确实,学习了。
    Anshi
        23
    Anshi  
       Feb 26, 2021   4
    悬赏 99.9 为什么会收到冷嘲热讽,是属于一个文化界限问题,要么一杯咖啡,对方当交个朋友,而选中帮你,要么完全不提供回馈,直接真诚提问,对方这是公益性质的帮你,如果选择一个实际的数字量化,那就需要好好讨论,帮你这个事情变得复杂,它到底值多少钱,多了,显得势力,少了,不划算,变成了人性的问题。
    Ritter
        24
    Ritter  
       Feb 26, 2021
    100 块不少了 可惜我不会
    NasirQ
        25
    NasirQ  
       Feb 26, 2021
    抛开其他,我觉得楼主出价有问题。首先所谓 "99.9" "9.9" 这样子定价,是商家为了满足顾客的省钱心里做的定价策略。然而楼主是在寻求技术支持。这里建议改为 0.1k 或者 0.1011k,这样二进制形式的数字更能吸引人 [dog]
    daoyouma
        26
    daoyouma  
       Feb 26, 2021
    10 分钟能解答 我不介意 关键 我不会
    yolee599
        27
    yolee599  
       Feb 26, 2021 via Android
    char *r = "1234"; 要改成 const char *r = "1234";
    yolee599     28
    yolee599  
       Feb 26, 2021 via Android
    @yolee599 说错了要改成 static const char *r = "1234";
    aheadlead
        29
    aheadlead  
       Feb 26, 2021
    ………………………楼上这

    我来回答一下吧。楼主你在 World() 里定义的变量 char *r 是在 World() 这次函数调用的栈帧里的。
    World() 函数返回后,栈帧弹出,char *r 本身所占据的 8 字节内存就不应该访问了。

    虽然你仍然有可能能访问到,但这属于 undefined behavior 。
    我对 Flutter 一无所知,但有可能是就是你访问了不该访问的内存(比如提示 memory access violation 、segmentation fault 之类的)。

    至于你说 Test() 函数也会闪退。Test() 函数本身没有任何问题(只是没啥意义),可能和你的用法有关。楼主要是不嫌麻烦的话,把代码放到 github 或者 gist/pastebin 上,我可以一看。
    aheadlead
        30
    aheadlead  
       Feb 26, 2021
    补充一下,char *r 所指向的内存是在 rodata 段,这块区域的内存可以随意访问。
    导致访问出错的不是 r 指向的内存,而是访问 r 本身。

    FYR: https://en.wikipedia.org/wiki/Data_segment
    aheadlead
        31
    aheadlead  
       Feb 26, 2021
    hanssx
        32
    hanssx  
       Feb 27, 2021
    @aheadlead 请教个问题,我对 c 语言也不熟,我 World()函数返回的应该是"1234"的内存地址吧?"1234"是在堆上分配的吗?如果是的话,World()函数返回值应该还能索引到"1234"这块内存吧?
    aheadlead
        33
    aheadlead  
       Feb 27, 2021
    @hanssx #31 你这么一说还真是。。。看来好几年没写 C 还犯错了,糗大了

    你说的是正确的,昨天我发的那个代码还多此一举了,抱歉浪费各位时间。

    准确的说,楼主位的代码是不会造成我说的那种内存错误。楼主可以抓个 bugreport 看下 native 的 log 是什么。
    realpg
        34
    realpg  
    PRO
       Feb 27, 2021
    提问良好,字多并不嗦,值得鼓励
    realpg
        5
    realpg  
    PRO
       Feb 27, 2021
    @NasirQ #25
    真的 99.9 这种会遭人反感的

    但是 0.0001M 估计会有码农开心的愿意的
    cz5424
        36
    cz5424  
       Feb 27, 2021 via iPhone
    建议楼主看一下 C 语言的指针部分,函数内分配的内存不要再返回出去,容易内存泄露
    caiyue1993
        37
    caiyue1993  
       Feb 27, 2021
    阴阳怪气的人真多啊,“请尽量让自己的恢复能够对别人有帮助”
    taogen
        38
    taogen  
       Feb 27, 2021
    99.9 充满资本的铜臭味道
    phpIsNumberOne
        39
    phpIsNumberOne  
    OP
       Feb 27, 2021   2
    找到问题了,主要是我更新代码后使用得是热重载(Hot reload),和想象的不太一样,so 文件好像并没有更新,致使我写了正确的代码也没有正确的反馈;将 APP 卸载重新编译即可。

    至于 C 内存的问题,并没有考虑那么多,只想先跑通再说;而且我实际也不是用的 C,而是用的 go(CGO);使用 C 尝试就是因为没有给我正常的反馈,还以为是 CGO 的问题。

    再补充两点:
    动态库的名称应该以 lib 开头,否则项目以 release 运行时会找不到;
    go 函数中不能写 defer C.free(unsafe.Pointer(r))释放内存,应该 dart 取到值后再释放。
    phpIsNumberOne
        40
    phpIsNumberOne  
    OP
       Feb 27, 2021
    @hanxiV2EX
    @oxromantic
    @aheadlead
    感谢你们的热心解答
    About     Help     Advertise     Blog     API     FAQ     Solana     3598 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 96ms UTC 04:42 PVG 12:42 LAX 21:42 JFK 00:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86