Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support integrating with C/C++ in plugin framework #7053

Closed
jtrunick opened this issue Nov 28, 2016 · 174 comments
Closed

Support integrating with C/C++ in plugin framework #7053

jtrunick opened this issue Nov 28, 2016 · 174 comments
Assignees
Labels
c: new feature Nothing broken; request for a new capability dependency: dart Dart team may need to help us engine flutter/engine repository. See also e: labels. package flutter/packages repository. See also p: labels. platform-android Android applications specifically
Milestone

Comments

@jtrunick
Copy link

jtrunick commented Nov 28, 2016

It would be nice to have an example of calling C/C++ code, or at least how to build native code along with a Flutter app. This may purely a Gradle question, but its not clear to someone that's not an expert on Gradle (for example, me), how to pull this off.


Admin comment: Please see dart-lang/sdk#34452 for current status and additional information

@chinmaygarde
Copy link
Member

@jason-simmons knows the most about Gradle. Once we have an .so, I can definitely help getting it loaded.

@jtrunick
Copy link
Author

jtrunick commented Dec 2, 2016

I did find that under buildSrc there is another property for setting the gradle build version. After updating to 2.2.2 I've progressed, and was able to verify the .so loads, and is callable from Java.

@eseidelGoogle
Copy link
Contributor

Presumably we would also need to add a C API for sending HostMessages from C/C++ code to Dart.

@jtrunick
Copy link
Author

jtrunick commented Dec 6, 2016

Yes please. I have a suspicion that the C->Java callback may not be cheap.

@mit-mit mit-mit changed the title C/C++ Example Support integrating with C/C++ in plugin framework Feb 2, 2017
@mit-mit mit-mit added this to the 4: Make shippers happy milestone Feb 2, 2017
@ijustlovemath
Copy link

Any update on this? Considering Flutter for building a cross platform app that calls C++ code compiled into a shared library, and this is the only major stopping point.

@eseidelGoogle
Copy link
Contributor

This is possible today (and @jtrunick did so in his shipping app), but you have to bounce through Java or Obj-C first.

i.e. you can use https://flutter.io/platform-channels/ to talk from Dart to Obj-C/Java and then from Obj-C/Java call into your C++ code. This bug covers adding more direct support for this, and potentially avoiding the Obj-C/Java passthrough.

@timotheecour
Copy link

timotheecour commented Sep 20, 2017

Since Dart VM is implemented in C++ shouldn't there be an easier (if less safe) way to call C shared libraries directly (say via dlopen) ? How much change would be required for basic (unsafe/experimental) support?

Is something like this: https://www.dartlang.org/articles/dart-vm/native-extensions available on android or ios?

@mehmetf
Copy link
Contributor

mehmetf commented Oct 2, 2017

We have heard this requirement from a couple of Google apps:

  • One such app wrote their own C++ libraries for operating the camera to reduce latency. These libraries are platform specific and optimized to work as quickly as possible. Invoking these libraries with the lowest possible latency is critical for such apps. Forcing them to go through PlatformChannel + JNI will not achieve that on Android.

  • There are advanced mobile teams out there who write business logic components in C++ to be able to share it between their Android and iOS implementations. Flutter supporting direct integration with those libraries would further cement its position of being the best cross-platform framework out there.

I don't think this is a must have. However, this is one area that Flutter can further differentiate itself from other cross-platform solutions.

@Hixie
Copy link
Contributor

Hixie commented Oct 2, 2017

One such app wrote their own C++ libraries for operating the camera to reduce latency. [...] Forcing them to go through PlatformChannel + JNI will not achieve that on Android.

What was their solution on Android for getting from C++ to Java and back?

@chinmaygarde
Copy link
Member

If it is really necessary, we can allow Dart native extensions on the mobile platforms. Right now, we don't expose the symbols in dart_api.h. We will need to decide on the following before we can flip the switch:

  • Figure out how to make the AOT compiler aware of Dart code whose sole entry point is from a method that may not be in the main Flutter engine dynamic library. Otherwise, the tree shaking pass may get rid of the code.
  • Provide guidance on building and packaging native extensions (Gradle & Xcode for Android & iOS respectively).
  • Provide some ABI stability guarantees for the routines in dart_api.h. Though it is mostly stable, I believe it is still evolving to account for the various modes.

So far, the platforms channels mechanism seems to have been adequate for the simpler use cases.

@mehmetf
Copy link
Contributor

mehmetf commented Oct 3, 2017

What was their solution on Android for getting from C++ to Java and back?

I have not looked deeply into their use case. It seemed that they have written all the bits that need very low-latency communication in C++. I will ask whether they use any JNI for performance-critical use cases (my gut feeling is no).

It really depends on what we can do on Flutter side. If we can supply an interop that's significantly faster than JNI, it would be a big win for these teams. They can shrink their C++ codebase and shift more to the app side. If our interop performance is comparable to JNI then I don't see a big win here. They could probably continue what they are doing now and use PlatformChannel.

This is about giving such teams an extra reason to switch to Flutter. I have not heard of this being a blocker, so prioritize accordingly.

@Hixie
Copy link
Contributor

Hixie commented Oct 3, 2017

If I understand what you're saying correctly, you're saying current solutions are to have all the logic (camera+UI) in C++ with minimal logic in Java, and the desire is to move the UI part of this logic to Dart, without losing the low-latency UI<->camera interactivity.

@Hixie
Copy link
Contributor

Hixie commented Oct 3, 2017

Can you talk about what their threading situation is like? Do they just have the one thread for camera+UI?

@sethladd sethladd mentioned this issue Oct 3, 2017
@eseidelGoogle
Copy link
Contributor

@chinmaygarde might move us closer to solving this with his current work on the embedder API.

@binoypatel
Copy link

+1

@WoodyGuo
Copy link

WoodyGuo commented Dec 28, 2017

Any progress with this issue?

We've already been using djinni to share logics across different platforms. It would be great if we can have interop between Dart and C++, rather than having to go back and forth through Java/Objc-C.

@loint
Copy link

loint commented Jan 23, 2018

If Dart can integrate with C/C++ I think it's a great idea for mobile to re-use a ton of native library and no need binding to a specific platform using JNI or Objective C++.

@nielsenko
Copy link

Have you considered https://github.com/mono/CppSharp? They already have the parsing and AST in place for c++, as well as support for multiple target languages. Perhaps you could create a Dart generator for CppSharp?

@srmncnk
Copy link

srmncnk commented Aug 12, 2019 via email

@vladest
Copy link

vladest commented Aug 12, 2019

Qt is C++ and QML (JS engine)
What license? LGPL? GPL? what is wrong with it?

@rmtmckenzie
Copy link
Contributor

rmtmckenzie commented Aug 12, 2019

First off IANAL, but as I understand it most of Qt is LGPL (the IDE etc are GPL), which means that it has language that while not expressly forbidding static linking, makes it difficult to do while still adhering to the licence if your application is closed-source.

Technically, if you use only LGPL and provide your object files (and probably instructions) so that users could potentially re-link against a different version of the library, you're satisfying the requirements of the LGPL. But I'm pretty sure the Qt Company doesn't advertise that fact, so the common conception is that you can't deploy static libraries which means you can't get your app released on the app store without paying their extortionate licensing fees. And I may be wrong about providing object files, that's just my understanding of it, and I don't know if any companies are doing that.

Android is easier because it does allow dynamically loaded libraries which are more explicitly allowed under the LGPL, but in all honestly static linking would probably be preferable there too to keep the app size down which means running into the same issue.

@MarkIngramUK
Copy link

Hi @cpboyd , I think I'm looking at this from the opposite direction. We already have apps built on platform specific UI frameworks, where each platform allows us to utilise our vast collection of existing C++ libraries. I understand Flutter is cross-platform, which is great, but unless I can actually use it (with my existing code), then I'm better off just sticking with non-cross-platform UI. The only sticking point comes when a future OS (e.g. Fuchsia) requires the use of Flutter & Dart, but doesn't allow for this use-case. In that case it's likely to be ignored by anyone with large existing codebases.

I guess I'm not sure whether Flutter / Dart are being designed with "web" apps (i.e. where backends are on the web) in mind, or serious consideration is being given to the needs of professional desktop application developers. Ultimately decisions like this can affect the number of, and quality of, many applications on an app store. If I can write a high quality professional app for iOS using UIKit, utilising millions of lines of existing code, but I can't (with near-zero performance cost) if I'm developing for Fuchsia / Flutter / Dart, then that would be an OS & platform that I wouldn't develop for.

The aim of my posts is not to compare Flutter to other cross-platform or non-cross-platform libraries, it's to highlight use cases that are important to a subset of developers.

The Dart FFI is interesting, from the very brief read of the sqllite example, it looks similar to C# with PInvoke, but unfortunately that's not suitable for C++, as either nearly every type you deal with would need wrapping, or you would have to write some fully generic type-less interface system to wrap the C++. Neither of those are particularly appealing when you compare it to the ease of the following Obj-C class:

#include <mylib/mytype.h>
@implementation MyView
{
    MyLib::MyType *_pMyType;
}
@end

Or UWP with C++/WinRT:

#include <mylib/mytype.h>
class MyUserControl : public UserControl
{
    MyLib::MyType *_pMyType;
};

Thanks :-)

@Hixie @MarkIngramUK Neither of those are cross-platform, which was my point.
AppKit is Apple-only, while UWP is Windows-only.
Perhaps if Flutter had used Swift or C# instead of Dart, then we'd already have the same level of support, but that's an entirely different argument.
Xamarin might be a more appropriate comparison than UWP, but Xamarin's cross platform views weren't nearly as customizable as Flutter's and often required a lot of native code to get looking decent.
My suggestion still remains: If you want to use Flutter with C++, you should participate in the Dart team's FFI preview and help improve support for all of us 😃

@cpboyd
Copy link

cpboyd commented Aug 12, 2019

This issue is about language feature and should not be mixed with UI widget API design.

@atsushieno Sure, and that's why this discussion would be more productive on the Dart FFI forum... Flutter is the framework. Dart is the language.

Neither of those are particularly appealing when you compare it to the ease of the following Obj-C class:

@MarkIngramUK I'm sure that's exactly the kind of feedback that the Dart team would love to see over at https://groups.google.com/forum/#!forum/dart-ffi

@paulocoutinhox
Copy link

I have a project called ezored (https://ezored.com) that is a C++ bootstrap project for SDKs and applications in C++. We are using in mobile projects (android and iOS). Im waiting for FFI be finished to create a project that will use the default SDK into flutter.

We don't have any problems with C++ and the time of dev new features are reduced, since the SDK has the same code into all platforms, as you can see in the default implementation (poco project, openssl, sqlite, specific platform code integrated with bridge code etc).

In my option this is the best way:

  • iOS and Android with C++ backend (ezored)
  • Flutter and C++ as backend

Feel free to add a start to the project :)

@vincentsong
Copy link

Kotlin Multiplatform could be a workaround, not perfect thought. Still need to wait for dart-lang/sdk#34452

@pzoltowski
Copy link

Unity3d seems is somehow porting flutter to their engine which is based on C# VM [1] - in that world talking between C# and C++ is decent. Maybe worth to take a look at their repo how they solved some issues. They state: "UIWidgets is mainly derived from Flutter". I would also have a look at react native camp and their new approach with TurboModules - their solution might have edge over flutter approach since will be

  1. both synchronous and asynchronous and
  2. there won't be any marshalling and
  3. will support not only C but C++

I'm cheer-leading both camps.

[1] https://github.com/UnityTech/UIWidgets

@mit-mit
Copy link
Member

mit-mit commented Sep 10, 2019

As of Dart 2.5, this (dart:ffi) is now in preview:
https://medium.com/dartlang/announcing-dart-2-5-super-charged-development-328822024970

@RohovDmytro
Copy link

RohovDmytro commented Sep 24, 2019

Great news!

Mmm... Will it be enough to use Oboe with Flutter?..

https://github.com/google/oboe

@sjindel-google
Copy link
Contributor

@rg4real Yep! But, you'll need to write some C wrappers since the Oboe interface is in C++.

You can see https://github.com/flutter/flutter/wiki/Binding-to-native-code-via-FFI for instructions on getting started.

@atsushieno
Copy link

You can reuse my oboe-c.so that I wrote for my C# bindings, if that works https://github.com/atsushieno/oboe-sharp/tree/master/native

@RohovDmytro
Copy link

@sjindel-google , that are some awesome news!

So I need to create a bridge between C++ and C code by creating classes and functions. And then I can use that classes and call that function from a Dart code. I think that's right.

@atsushieno , thank you. I am taking a look. I am not sure how to make bridges in my case (lack of experience). But did you manage to achieve your overall goal of precise playing with oboe? Was it that good?

@atsushieno
Copy link

@rg4real I was doing that merely for simpler API (compared to OpenSLES) than low latency audio. If I were really serious about latency then I wouldn't use Xamarin.Android. If you are talking about Oboe (or AAudio behind it), then I do use it in Fluidsynth and it works well. Not sure "how good" AAudio is compared to OpenSLES though.

@bhauj
Copy link

bhauj commented Oct 23, 2019

Is there any guide on how memory gets managed?

If C++ code creates a memory using new/malloc and returns to dart code, how to free that memory.

c++ code
void foo(char** out) {
*out = new char[25];
}

How delete the memory assigned to |out| variable from dart code?

@dcharkes
Copy link
Contributor

If you're on Dart 2.5, there's a .free() on Pointer. If you're on dev/master branch this method moved package:ffi https://github.com/dart-lang/ffi/blob/master/lib/src/allocation.dart#L70.

@gaaclarke gaaclarke added the platform-android Android applications specifically label Oct 23, 2019
@bhauj
Copy link

bhauj commented Oct 24, 2019

As per comment - "It may only be used against pointers allocated in a manner equivalent to [allocate]." - free() can be used only if memory is allocated using allocate() method.

e.g.
ffi.Pointer ptr = ffi.Pointer.allocate();
ptr.free();

Does this take care of freeing memory which is allocated in C++ side using either new or malloc from dart code?

@dcharkes
Copy link
Contributor

As long as the memory was allocated through malloc, either via Dart or C++, it can be freed with free.

In Dart 2.6 we use DynamicLibrary.lookupFunction("free") to define free in Dart, so it will be exactly the same free as in the C++ part of the program. (Unless you're linking in multiple versions of free into your binary.)

@mit-mit
Copy link
Member

mit-mit commented Jan 6, 2020

Closing this issue as this feature is now generally available (in beta) in all Flutter channels. We're continue to improve the issue. For any detailed issues, please file them in https://github.com/dart-lang/sdk/issues/new.

@mit-mit mit-mit closed this as completed Jan 6, 2020
@KaungZawHtet
Copy link

making c++ classes to c compatibility is messy. plz make capability to directly call c++ classes

@fzyzcjy
Copy link
Contributor

fzyzcjy commented Jan 8, 2020

+1 Can we have C++ support?

@dnfield
Copy link
Contributor

dnfield commented Jan 8, 2020

@KaungZawHtet and @fzyzcjy - please consider opening a new issue (probably in dart-lang rather than flutter) for this.

I'm going to lock this issue - there are a lot of people subscribed to it, but it's original goal is pretty clearly resolved.

@flutter flutter locked as resolved and limited conversation to collaborators Jan 8, 2020
@mit-mit
Copy link
Member

mit-mit commented Jan 8, 2020

Yes, for new issues, please file them using this link: https://github.com/dart-lang/sdk/issues/new?labels=library-ffi,area-vm

@flutter-triage-bot flutter-triage-bot bot added the package flutter/packages repository. See also p: labels. label Jul 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: new feature Nothing broken; request for a new capability dependency: dart Dart team may need to help us engine flutter/engine repository. See also e: labels. package flutter/packages repository. See also p: labels. platform-android Android applications specifically
Projects
None yet
Development

No branches or pull requests