mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 19:05:42 +00:00
[vm/ffi] Remove platform specific logic from DynamicLibrary.open
Change-Id: Id69e17563c4d64f6ead5e143077a7364520f65a0 Reviewed-on: https://dart-review.googlesource.com/c/93173 Auto-Submit: Daco Harkes <dacoharkes@google.com> Reviewed-by: Samir Jindel <sjindel@google.com> Commit-Queue: Samir Jindel <sjindel@google.com>
This commit is contained in:
parent
6a5c9597c6
commit
3abc7d34d7
|
@ -19,51 +19,14 @@
|
|||
|
||||
namespace dart {
|
||||
|
||||
// Concatenates a NULL terminated array of strings.
|
||||
// The returned string is scope allocated.
|
||||
// TODO(dacoharkes): Can we share this with runtime/bin/extensions.cc?
|
||||
const char* Concatenate(const char** strings) {
|
||||
int size = 1; // null termination.
|
||||
for (int i = 0; strings[i] != NULL; i++) {
|
||||
size += strlen(strings[i]);
|
||||
}
|
||||
char* result = reinterpret_cast<char*>(Dart_ScopeAllocate(size));
|
||||
int index = 0;
|
||||
for (int i = 0; strings[i] != NULL; i++) {
|
||||
index += snprintf(result + index, size - index, "%s", strings[i]);
|
||||
}
|
||||
ASSERT(index == size - 1);
|
||||
ASSERT(result[size - 1] == '\0');
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO(dacoharkes): Can we share this with runtime/bin/extensions.cc?
|
||||
const char* LibraryPath(const char* library_name) {
|
||||
const char* library_prefix = "lib";
|
||||
#if defined(TARGET_OS_LINUX)
|
||||
const char* library_extension = "so";
|
||||
#elif defined(TARGET_OS_MACOS)
|
||||
const char* library_extension = "dylib";
|
||||
#else
|
||||
const char* library_extension = "";
|
||||
UNREACHABLE();
|
||||
#endif
|
||||
|
||||
const char* path_components[] = {
|
||||
library_prefix, library_name, ".", library_extension, NULL,
|
||||
};
|
||||
|
||||
return Concatenate(path_components);
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) {
|
||||
#if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
|
||||
UNREACHABLE();
|
||||
#else
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(String, argName, arguments->NativeArgAt(0));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(String, lib_path, arguments->NativeArgAt(0));
|
||||
|
||||
dlerror(); // Clear any errors.
|
||||
void* handle = dlopen(LibraryPath(argName.ToCString()), RTLD_LAZY);
|
||||
void* handle = dlopen(lib_path.ToCString(), RTLD_LAZY);
|
||||
if (handle == nullptr) {
|
||||
char* error = dlerror();
|
||||
const String& msg = String::Handle(
|
||||
|
|
18
samples/ffi/dylib_utils.dart
Normal file
18
samples/ffi/dylib_utils.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:ffi' as ffi;
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
String _platformPath(String name, {String path}) {
|
||||
if (path == null) path = "";
|
||||
if (Platform.isLinux) return path + "lib" + name + ".so";
|
||||
if (Platform.isMacOS) return path + "lib" + name + ".dylib";
|
||||
throw Exception("Platform not implemented");
|
||||
}
|
||||
|
||||
ffi.DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
|
||||
String fullPath = _platformPath(name, path: path);
|
||||
return ffi.DynamicLibrary.open(fullPath);
|
||||
}
|
|
@ -4,12 +4,14 @@
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
|
||||
|
||||
typedef DoubleUnOp = double Function(double);
|
||||
|
||||
main(List<String> arguments) {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
print(l);
|
||||
print(l.runtimeType);
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
typedef NativeUnaryOp = ffi.Int32 Function(ffi.Int32);
|
||||
typedef NativeBinaryOp = ffi.Int32 Function(ffi.Int32, ffi.Int32);
|
||||
typedef UnaryOp = int Function(int);
|
||||
|
@ -93,7 +95,7 @@ main(List<String> arguments) {
|
|||
print('start main');
|
||||
|
||||
ffi.DynamicLibrary ffiTestFunctions =
|
||||
ffi.DynamicLibrary.open("ffi_test_functions");
|
||||
dlopenPlatformSpecific("ffi_test_functions");
|
||||
|
||||
{
|
||||
// int32 bin op
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
import 'coordinate.dart';
|
||||
|
||||
typedef NativeCoordinateOp = Coordinate Function(Coordinate);
|
||||
|
@ -33,7 +35,7 @@ main(List<String> arguments) {
|
|||
print('start main');
|
||||
|
||||
ffi.DynamicLibrary ffiTestFunctions =
|
||||
ffi.DynamicLibrary.open("ffi_test_functions");
|
||||
dlopenPlatformSpecific("ffi_test_functions");
|
||||
|
||||
{
|
||||
// pass a c pointer to a c function as an argument to a c function
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
import 'coordinate.dart';
|
||||
|
||||
typedef NativeCoordinateOp = Coordinate Function(Coordinate);
|
||||
|
@ -12,7 +14,7 @@ main(List<String> arguments) {
|
|||
print('start main');
|
||||
|
||||
ffi.DynamicLibrary ffiTestFunctions =
|
||||
ffi.DynamicLibrary.open("ffi_test_functions");
|
||||
dlopenPlatformSpecific("ffi_test_functions");
|
||||
|
||||
{
|
||||
// pass a struct to a c function and get a struct as return value
|
||||
|
|
18
tests/standalone_2/ffi/dylib_utils.dart
Normal file
18
tests/standalone_2/ffi/dylib_utils.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:ffi' as ffi;
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
String _platformPath(String name, {String path}) {
|
||||
if (path == null) path = "";
|
||||
if (Platform.isLinux) return path + "lib" + name + ".so";
|
||||
if (Platform.isMacOS) return path + "lib" + name + ".dylib";
|
||||
throw Exception("Platform not implemented");
|
||||
}
|
||||
|
||||
ffi.DynamicLibrary dlopenPlatformSpecific(String name, {String path}) {
|
||||
String fullPath = _platformPath(name, path: path);
|
||||
return ffi.DynamicLibrary.open(fullPath);
|
||||
}
|
|
@ -8,6 +8,8 @@ library FfiTest;
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -20,13 +22,13 @@ void main() {
|
|||
}
|
||||
|
||||
void testOpen() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
Expect.notEquals(null, l);
|
||||
}
|
||||
|
||||
void testOpenError() {
|
||||
Expect.throws(
|
||||
() => ffi.DynamicLibrary.open("doesnotexistforsurelibrary123409876"));
|
||||
() => dlopenPlatformSpecific("doesnotexistforsurelibrary123409876"));
|
||||
}
|
||||
|
||||
typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
|
||||
|
@ -34,30 +36,30 @@ typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
|
|||
typedef DoubleUnOp = double Function(double);
|
||||
|
||||
void testLookup() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
|
||||
Expect.approxEquals(12.0, timesFour(3));
|
||||
}
|
||||
|
||||
void testLookupError() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
Expect.throws(() => l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>(
|
||||
"functionnamethatdoesnotexistforsure749237593845"));
|
||||
}
|
||||
|
||||
void testToString() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
Expect.stringEquals(
|
||||
"DynamicLibrary: handle=0x", l.toString().substring(0, 25));
|
||||
}
|
||||
|
||||
void testEquality() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l2 = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
Expect.equals(l, l2);
|
||||
Expect.equals(l.hashCode, l2.hashCode);
|
||||
Expect.notEquals(l, null);
|
||||
Expect.notEquals(null, l);
|
||||
ffi.DynamicLibrary l3 = ffi.DynamicLibrary.open("ffi_test_functions");
|
||||
ffi.DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
|
||||
Expect.notEquals(l, l3);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ library FfiTest;
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
import 'coordinate.dart';
|
||||
|
@ -24,7 +26,7 @@ void main() {
|
|||
}
|
||||
|
||||
ffi.DynamicLibrary ffiTestFunctions =
|
||||
ffi.DynamicLibrary.open("ffi_test_functions");
|
||||
dlopenPlatformSpecific("ffi_test_functions");
|
||||
|
||||
/// pass a pointer to a c function as an argument to a c function
|
||||
void testFunctionWithFunctionPointer() {
|
||||
|
|
|
@ -9,6 +9,8 @@ library FfiTest;
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
import 'coordinate.dart';
|
||||
|
@ -23,7 +25,7 @@ void main() {
|
|||
}
|
||||
|
||||
ffi.DynamicLibrary ffiTestFunctions =
|
||||
ffi.DynamicLibrary.open("ffi_test_functions");
|
||||
dlopenPlatformSpecific("ffi_test_functions");
|
||||
|
||||
/// pass a struct to a c function and get a struct as return value
|
||||
void testFunctionWithStruct() {
|
||||
|
|
|
@ -8,6 +8,8 @@ library FfiTest;
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
void main() {
|
||||
|
@ -29,7 +31,7 @@ void main() {
|
|||
}
|
||||
|
||||
ffi.DynamicLibrary ffiTestFunctions =
|
||||
ffi.DynamicLibrary.open("ffi_test_functions");
|
||||
dlopenPlatformSpecific("ffi_test_functions");
|
||||
|
||||
typedef NativeBinaryOp = ffi.Int32 Function(ffi.Int32, ffi.Int32);
|
||||
typedef UnaryOp = int Function(int);
|
||||
|
|
|
@ -8,6 +8,8 @@ library FfiTest;
|
|||
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
import 'dylib_utils.dart';
|
||||
|
||||
void main() {
|
||||
testGetGeneric();
|
||||
testGetGeneric2();
|
||||
|
@ -245,7 +247,7 @@ void testFromFunctionTearOff() {
|
|||
|
||||
void testLookupFunctionGeneric() {
|
||||
Function generic<T extends Function>() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
Function result;
|
||||
result = l.lookupFunction<T, DoubleUnOp>("cos"); //# 15: compile-time error
|
||||
return result;
|
||||
|
@ -256,7 +258,7 @@ void testLookupFunctionGeneric() {
|
|||
|
||||
void testLookupFunctionGeneric2() {
|
||||
Function generic<T extends Function>() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
Function result;
|
||||
result = //# 16: compile-time error
|
||||
l.lookupFunction<NativeDoubleUnOp, T>("cos"); //# 16: compile-time error
|
||||
|
@ -267,12 +269,12 @@ void testLookupFunctionGeneric2() {
|
|||
}
|
||||
|
||||
void testLookupFunctionWrongNativeFunctionSignature() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
l.lookupFunction<IntUnOp, IntUnOp>("cos"); //# 17: compile-time error
|
||||
}
|
||||
|
||||
void testLookupFunctionTypeMismatch() {
|
||||
ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
|
||||
ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
|
||||
l.lookupFunction<NativeDoubleUnOp, IntUnOp>("cos"); //# 18: compile-time error
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue