मैं डार्ट के एफएफआई पैकेज और MYSQL के मूल सी-कनेक्टर का उपयोग करके डार्ट के साथ सीधे MYSQL से कनेक्ट करने का प्रयास कर रहा हूं।

मेरा डार्ट कोड है:

import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef CFun = Pointer Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Pointer>?);
typedef DartFun = Pointer Function(Pointer<Utf8>, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Pointer>?);

void main() {
  final lib = DynamicLibrary.open('/usr/lib64/libmysqlcppconn8.so.2');
  final fc = lib.lookup<NativeFunction<CFun>>('mysqlx_get_session');
  print('We have C: $fc');
  final DartFun fd = fc.asFunction();
  print('We have Dart: $fd');
  Pointer<Pointer>? error;
  Pointer? session;
  session = fd('localhost'.toNativeUtf8(), 33060, '*user*'.toNativeUtf8(), '*password*'.toNativeUtf8(), ''.toNativeUtf8(), error);
}

इसे चलाने पर मुझे यह आउटपुट मिलता है:

We have Pointer<NativeFunction<(Pointer<Utf8>, Int32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Pointer<NativeType>>?) => Pointer<NativeType>>>: address=0x7f5b9c78f770
We have Closure: (Pointer<Utf8>, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Pointer<NativeType>>?) => Pointer<NativeType>
Unhandled exception:
NoSuchMethodError: The method 'FfiTrampoline' was called on null.
Receiver: null
Tried calling: FfiTrampoline()
#0      FfiTrampoline (dart:ffi)
#1      main (package:greudb/src/connection.dart:37:14)
#2      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

सी में इसे आजमाने से यह पूरी तरह से काम करता है:

#include <mysql-cppconn/mysqlx/xapi.h>
#include <stdio.h>

int main()
{
    mysqlx_session_t *session = 0;
    mysqlx_error_t *error = 0;
    session = mysqlx_get_session("localhost", 33060, "*user*", "*password*", "", &error);
    if(error != 0) {
        printf("%s/n", mysqlx_error_message(error));
    }
    return 0;
}

मुझे लगता है कि मेरे डार्ट फंक्शन हस्ताक्षर सही नहीं हैं, लेकिन इससे कोई फर्क नहीं पड़ता कि मैं क्या कोशिश करता हूं यह मदद नहीं करता है। MySQL का C दस्तावेज़ यहाँ है: https://dev.mysql। com/doc/dev/connector-cpp/8.0/group__xapi__sess.html

मैं Linux Fedora 33, MySQL समुदाय सर्वर 8, MySQL कनेक्टर C/C++ 8, डार्ट 202.8488 का उपयोग कर रहा हूं।

1
Gerastios 11 जून 2021, 10:49
मेरी भावना यह है कि मुद्दा अंतिम तर्क (mysqlx_error_t **error) का सही अनुवाद कर रहा है। यदि आप इसे nullptr के साथ चलाते हैं, तो ऐसा लगता है कि यह पूरा हो गया है। हालांकि, मुझे यकीन नहीं है कि इससे कैसे निपटें।
 – 
msbit
11 जून 2021, 14:02

1 उत्तर

सबसे बढ़िया उत्तर

चारों ओर देखने के बाद, ऐसा प्रतीत होता है आप इसके लिए उपयुक्त प्रकार बना सकते हैं error का उपयोग कर:

final error = calloc<Pointer>();

जो हुड के तहत calloc.allocate<Pointer>(...) को उपयुक्त byteCount के साथ कॉल करता है। चूंकि यह अप्रबंधित स्मृति है, इसलिए आपको कॉल करके इसे जारी करना याद रखना होगा:

calloc.free(error);

एक बार जब आप इसके साथ कर लेंगे।

शुक्र है, ऐसा लगता है कि mysqlx एपीआई सभी संरचनाओं को अपारदर्शी मानता है, इसलिए आप यह निर्धारित कर सकते हैं कि निम्नलिखित की तरह कुछ करके वास्तविक त्रुटि क्या थी:

final message = errorMessage(error.value);
print(message.toDartString());

स्मृति जारी करने के विषय पर, toNativeUtf8() को कॉल करके बनाए गए Pointer<Utf8> मानों को भी मुक्त करने की आवश्यकता है।

वह सब एक साथ रखना:

import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef _GetSession = Pointer Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Pointer>);
typedef GetSession = Pointer Function(Pointer<Utf8>, int, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Pointer>);

typedef _CloseSession = Void Function(Pointer);
typedef CloseSession = void Function(Pointer);

typedef _ErrorMessage = Pointer<Utf8> Function(Pointer);
typedef ErrorMessage = Pointer<Utf8> Function(Pointer);

void main() {
  final lib = DynamicLibrary.open('/usr/lib64/libmysqlcppconn8.so.2');
  final GetSession getSession = lib.lookup<NativeFunction<_GetSession>>('mysqlx_get_session').asFunction();
  final CloseSession closeSession = lib.lookup<NativeFunction<_CloseSession>>('mysqlx_session_close').asFunction();
  final ErrorMessage errorMessage = lib.lookup<NativeFunction<_ErrorMessage>>('mysqlx_error_message').asFunction();

  final host = 'localhost'.toNativeUtf8();
  final user = 'user'.toNativeUtf8();
  final password = 'password'.toNativeUtf8();
  final database = ''.toNativeUtf8();
  final error = calloc<Pointer>();

  final session = getSession(host, 33060, user, password, database, error);

  calloc.free(host);
  calloc.free(user);
  calloc.free(password);
  calloc.free(database);

  if (error.value != nullptr) {
    final message = errorMessage(error.value);
    print(message.toDartString());

    calloc.free(error);
    return;
  }

  // Do something with session

  closeSession(session);
}
0
msbit 11 जून 2021, 15:15
बहुत बहुत धन्यवाद, इससे बहुत मदद मिलती है। जब मैं सही लॉगिन क्रेडेंशियल का उपयोग करता हूं तो यह पूरी तरह से काम करता है, अगर मैं कुछ गलत (गलत उपयोगकर्ता नाम की तरह) पास करता हूं तो मुझे सेगमेंटेशन गलती मिलती है। मुझे इसमें और गहराई से जाना है, फिर भी यह सबसे अधिक मददगार था।
 – 
Gerastios
16 जून 2021, 10:24
हर बार जब पुस्तकालय सी ++ अपवाद वर्ग फेंकता है तो मुझे सेगमेंटेशन गलती मिलती है। मुझे यकीन नहीं है कि यह एफएफआई की समस्या है, क्योंकि कनेक्टर पुस्तकालयों का उपयोग करने की कुछ सीमाएं हैं (जैसे बाइनरी पैकेज का उपयोग करने के बजाय इसे स्रोत से बनाना। फिर भी अगर मैं एक छोटी सी/सी ++ गतिशील लाइब्रेरी को रैपर और लिंक के रूप में बनाता हूं इसमें स्थिर कनेक्टर पुस्तकालय अपवादों को फेंकना अपेक्षित काम करता है। तो कम से कम मैं इसे वर्कअराउंड के रूप में कर सकता हूं।
 – 
Gerastios
16 जून 2021, 10:28
आह हाँ, सी ++ अपवाद। मुझे लगता है कि जैसा आपने वर्णन किया है, आपको इसे लपेटना होगा, और पुस्तकालय से उठाए गए किसी भी अपवाद को पकड़ना होगा। निश्चित रूप से एफएफआई का उपयोग करने की झुंझलाहट में से एक, अगर यह सी से अधिक जटिल है, तो यह मुश्किल हो जाता है।
 – 
msbit
16 जून 2021, 11:45