When I try to run my programm outside the QtCreator, the code crashes, when new QWebChannel(this) is called. I already checked DLL dependencies, but can't find the difference between running it from within the IDE and outside of it.
MyView::MyView() : ui(new Ui::MyView) {
ui->setupUi(this);
view = new QWebEngineView(this);
channel = new QWebChannel(this); // crash at this line
ui->content->addWidget(view);
connect(view, &QWebEngineView::loadFinished, this, &MyView::finishLoading);
view->page()->setWebChannel(channel);
channel->registerObject("controller", this);
view->load(QUrl("qrc:///res/index.html"));
}
In the project file I added QT += webengine webenginewidgets webchannel. Are there any other dependencies I may forgot?
Running windeployqt.exe copies all necessary dependencies (see https://doc.qt.io/qt-5/windows-deployment.html). Seames like some other resources nedded where causing the crash.
Related
I am working on a flutter project that runs fine in development.
However I do not know how to get the build to include dll's referenced using FFI.
I can't find clear instructions on how to do it.
I tried following the steps to build an msix here, which worked but didn't seem to include the dll (it fails in the same way as the regular build)
what is the procedure to have the build process consider the dll's?
other dll's show up in the build directory from 3rd party packages so there must be a way right?
That's really hard to discover by your own, but indeed you can bind those libraries to you MSIX. In my case I just made a package for label printers using Dart FFI and DLL`s provided by manufacturer and this is how I did it.
You need to add these DLL's to your assets setting on pubspec.yaml from your package. This is my case:
[...]
flutter:
[...]
assets:
- assets/WinPort.dll
- assets/Winppla.dll
- assets/Winpplb.dll
- assets/Winpplz.dll
With this setting you will embed your DLL files in your final MSIX, but this was the easy part. Now you have make sure to load the proper load these files in code.
Based on my own tests, I still dealing with two ways to develop and test code, the first one is when I am running a project in my machine via flutter run I must set the target for current.path, when I get it done and start building for deploy I change this to resolvedExecutable.parent.path. Where is what you need to do.
Loading you DLL in development environment (flutter run):
final String _packageAssetsDirPath = normalize(join(Directory.current.path,'assets'));
On production environment (running from .exe or MSIX installed):
final String _assetsPackageDir = normalize(
join('data', 'flutter_assets', 'packages', 'YOUR_PACKAGE_NAME', 'assets'));
final String _exeDirPath = File(Platform.resolvedExecutable).parent.path;
final String _packageAssetsDirPath =
normalize(join(_exeDirPath, _assetsPackageDir));
After with this var called _packageAssetsDirPath will be easy to load your DLL's, now you invoke a DynamicLibrary constructor:
// Path for DLL file
final String _libDllSourceFullPath =
normalize(join(_packageAssetsDirPath, 'Winppla.dll'));
// Target for copy, place DLL in same place the .exe you are running
final String _libDllDestFullPath =
normalize(join(_packageAssetsDirPath, 'YOUROWN.dll'));
// Try to copy for running exe path
File(_libDllSourceFullPath).copySync(_libDllDestFullPath);
// With this copy, would be simple to load, and if it fails, try in full path
// LOAD DLL
try {
String _packageAssetsDirPath =
normalize(join(Directory.current.path, 'assets'));
String _printerLibraryPath =
normalize(join(_packageAssetsDirPath, 'Winppla.dll'));
DynamicLibrary _library = DynamicLibrary.open(_printerLibraryPath);
return _library;
} catch (e) {
try {
DynamicLibrary _library = DynamicLibrary.open('Winppla.dll');
return _library;
} catch (e) {
// Avoing errors creating a fake DLL, but you could deal with an exception
return DynamicLibrary.process();
}
}
At this point you can load a DLL and use it, you can check my package full code at https://github.com/saviobatista/argox_printer check for lib/src/ppla.dart at function _setupDll() and you will see that loading.
I built a simpler option inspired in the solution of Sávio Batista
(You must have your .dll in your assets folder)
if (kReleaseMode) {
// I'm on release mode, absolute linking
final String local_lib = join('data', 'flutter_assets', 'assets', 'libturbojpeg.dll');
String pathToLib = join(Directory(Platform.resolvedExecutable).parent.path, local_lib);
DynamicLibrary lib = DynamicLibrary.open(pathToLib);
} else {
// I'm on debug mode, local linking
var path = Directory.current.path;
DynamicLibrary lib = DynamicLibrary.open('$path/assets/libturbojpeg.dll');
}
Just replace libturbojpeg.dll for your .dll
Background
I'm trying to auto-test my VSCode extension. The extension works with python files and uses vscode.executeDefinitionProvider and vscode.executeDocumentSymbolProvider on them.
Problem
vscode.executeDefinitionProvider always returns [], vscode.executeDocumentSymbolProvider always returns undefined.
Notes
When running the same code in a debug session of the extension (no test session), the commands work flawless.
I ensured the extensions to be available during the test and even manually activated them with
let ext = vscode.extensions.getExtension("ms-python.python");
assert.notStrictEqual (ext, undefined);
await ext?.activate ();
ext = vscode.extensions.getExtension("ms-python.vscode-pylance");
assert.notStrictEqual (ext, undefined);
await ext?.activate ();
Question
How do I get the commands to succeed during automated test.
Edit: Workaround
Apparently VSCode takes its time to really activate the extensions. I could get it working placing a await sleep (10000); in index.ts::run () before return new Promise((c, e) => {.
While this is working, it's a really unstable workaround, Is there any way to make the code wait until the whole environment is fully loaded?
In the end nothing really stably worked for me, so I resorted to the following (perfectly fine working) solution.
My auto tests are run from the productive environment, like any other extension.
In package.json I created a new command _test.
the command would run ./test/suite/index.ts : run().
Extension<T>::activate(): Thenable<T>
Returns: Thenable<T> - A promise that will resolve when this extension has been activated.
await ext?.activate();
I don't know why load_from_path does not work during sudo ninja install. It returns:
warning: unhandled error `GLib.Error'
css_provider.load_from_path ("com.github.saidbakr.quick-shutdown.css");
I tried to catch the exception, but the same Warning:
Gtk.CssProvider css_provider = new Gtk.CssProvider ();
try {
css_provider.load_from_path ("com.github.saidbakr.quick-shutdown.css");
}
catch (IOError e){
GLib.error("", e.message);
}
I checkedout the meson.build:
...
install_data(
join_paths('data', meson.project_name()+ '.css'),
install_dir: join_paths(get_option('datadir'))
)
The path of the file is added and it is installed to /usr/local/share
I don't know how to solve this issue.
The docs for Gtk.CssProvider.load_from_path() make no mention of searching in /usr/local/share/<app-data-dir> or any other standard directory. It's expecting an absolute path.
The standard way to solve this is to use GResource. If you're using a tutorial or template, it probably has something on GResource that you can use.
If not:
Create a file, quick-shutdown.gresource.xml, with the following:
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/com/github/saidbakr/quick-shutdown">
<file>com.github.saidbakr.quick-shutdown.css</file>
</gresource>
</gresources>
Add this to your meson.build:
gnome = import('gnome')
resources = gnome.compile_resources('com.github.saidbakr.quick-shutdown',
files('quick-shutdown.gresource.xml'),
)
Add resources to the list of sources in your executable() call in meson.build
Use Gtk.CssProvider.load_from_resource() instead: css_provider.load_from_resource ("/com/github/saidbakr/quick-shutdown/com.github.saidbakr.quick-shutdown.css")
Remove the meson code where you install the CSS file. It is now built directly into your executable.
For a real-world example of how to do this, check out the GNOME Clocks source code.
This may sound like a lot of steps, but it's the same steps as adding GtkBuilder UI files (or really any other kind of static file you need in your program). If you need to do that later, all you'll have to do is add <file> entries to the .gresource.xml file.
I have the following in ./js/parcel/build-js.js (it is more or less a simplification of exactly what the API docs example does, except that it takes an optional --watch argument):
#!/usr/bin/env node
const Bundler = require('parcel-bundler');
const path = require('path');
const watch = process.argv.indexOf('--watch') > 0;
if (watch) console.log('Watching files...');
(async function bundleJs() {
const jsBundler = new Bundler(path.join(__dirname, '../src/common.js'), {
watch,
hmr: false,
});
jsBundler.on('bundled', () => {
console.log('bundled!');
});
const bundle = await jsBundler.bundle();
console.log('done');
})();
When I run node js/parcel/build-js.js --watch, it detects the first change to src/common.js and prints:
Watching files...
✨ Built in 585ms.
bundled!
done
This is as I'd expect. When I edit and save src/common.js, it sees that and then the total output becomes (done gets deleted):
Watching files...
✨ Built in 585ms.
bundled!
✨ Built in 86ms.
bundled!
But after that, no file changes are detected. I make changes and save but it just sits there, producing no more output or updating the build. Why only once?
Note: If I do strace node js/parcel/build-js.js --watch, it seems to just sit on an unfinished epoll_wait(3,, which I guess means it's waiting for something, but maybe watching the wrong file...
Edit: Versions!
parcel-bundler: 1.12.3
node: 10.15.1
Ubuntu 18.04
Edit: using parcel watch
This appears to be a system-wide thing for me. I did yarn globals add parcel (which also installed 1.12.3), and now watching any JS file with parcel watch path/to/file.js does the same thing.
It turned out to be a conflict between Parcel's change detection and the default Vim setup. From the Hot Module Replacement docs:
Some text editors and IDE's have a feature called safe write that basically prevents data loss, by taking a copy of the file and renaming it when saved.
When using Hot Module Reload (HMR) this feature blocks the automatic detection of file updates, to disable safe write use the options provided below:
I added set backupcopy=yes to my .vimrc and it started working.
The solution for other editors is documented there as well.
It is a Parcel issue! I dropped it (until they fix it)
IMHO: I do not have to change my editor's behavior just to make bundler work correctly. (webpack works fine in the situation)
Using Cudafy version 1.29, which can be downloaded from here
I am executing the examples that are found in the install folder CudafyV1.29\CudafyByExample\
Specifically, "chapter 3" example that begins line 42 of program.cs calls the following:
simple_kernel.Execute();
which is this:
public static void Execute()
{
CudafyModule km = CudafyTranslator.Cudafy(); // <--exception thrown!
GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
gpu.Launch().thekernel(); // or gpu.Launch(1, 1, "kernel");
Console.WriteLine("Hello, World!");
}
The indicated line throws this exception:
Compilation error: CUDAFYSOURCETEMP.cu
'C:\Program' is not recognized as an internal or external command,
operable program or batch file. .
Which is immediately obvious that the path has spaces and the programmer did not double quote or use ~ to make it operational.
So, I did not write this code. And I cannot step through the sealed code contained within CudafyModule km = CudafyTranslator.Cudafy();In fact I don't even know the full path that is causing the exception, it is cut-off in the exception message.
Does anyone have a suggestion for how to fix this issue?
Update #1: I discovered where CUDAFYSOURCETEMP.cu lives on my computer, here it is:
C:\Users\humphrt\Desktop\Active Projects\Visual Studio
Projects\CudafyV1.29\CudafyByExample\bin\Debug
...I'm still trying to determine what the program is looking for along the path to 'C:\Program~'.
I was able to apply a workaround to bypass this issue. The workaround is to reinstall all components of cudafy in to folders with paths with no ' ' (spaces). My setup looks like the below screenshot. Notice that I also installed the CUDA TOOLKIT from NVIDIA in the same folder - also with no spaces in folder names.
I created a folder named "C:\CUDA" and installed all components within it, here is the folder structure: