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

PackageReferencing SQLitePCLRaw.bundle_green on Net6.0 app fails p/invoke #523

Open
WilliamXieMSFT opened this issue Nov 2, 2022 · 3 comments

Comments

@WilliamXieMSFT
Copy link

I noticed that the netstandard2.0 version of SQLitePCLRaw.batteries_v2.dll is missing NativeLibraries, but it exists in the net461 copy:
image

Since PackageReference uses the targetframework of the app, a .Net6.0 console app will load the netstandard2.0 dll and P/invoking SQLitePCL.raw.sqlite3_load_extension returns with a 1 (SQLITE_ERROR) and a null errmsg. If I change out the netstandard2.0 batteries_v2.dll for the net461 copy, the p/invoke succeeds.

Digging a bit into the source, the e_sqlite3 bundle imports different xmls per framework: SQLitePCL.raw/SQLitePCLRaw.bundle_e_sqlite3.csproj at master · ericsink/SQLitePCL.raw (github.com)

  <Import Condition=" '$(TargetFramework)' == 'netstandard2.0' " Project="..\msbuild_bundle_fragments\e_sqlite3_dllimport.xml" />
  <Import Condition=" '$(TargetFramework)' == 'net461' " Project="..\msbuild_bundle_fragments\e_sqlite3_dynamic.xml" />

For netstandard2.0, e_sqlite3_dllimport.xml just contains packagereferences.

For net461, e_sqlite3_dynamic.xml has the additional nativelibrary_for_netstandard2.cs which I believe would unblock our scenario.

Is there a reason for this discrepancy? Should e_sqlite3_dllimport also compile the nativelibrary_defines.cs and nativelibrary_for_netstandard2.cs? If not, will there be separate defines provided? Thanks for taking a look!


What version of SQLitePCLRaw are you using?

2.1.2 (latest as of this post)

If you are using one of the SQLitePCLRaw bundle packages, which one?

bundle_green

What platform are you running on? What operating system? Which version? What CPU?

Windows 10 - 64-bit Intel chip

What target framework are you building for? Are you on .NET Framework or the newer stuff (.NET Core, .NET 5+, etc)?

Net6.0 (building on Windows but plan to run it on both Windows & Linux)

Are you using the command line, or an IDE? Which IDE? Which version of that IDE?

dotnet 6.0 SDK & VS 2022

Is this problem something that just started happening? For example, were things working well for you and then you updated something and then the problem showed up? What changed?

this worked for framework project which used the batteries_v2.dll from net461, but it broke when I attempt to run in Net6.0 which pulls in the dll from the netstandard2.0 folder.

What is the exact error message you are seeing when the problem happens?

P/invoking SQLitePCL.raw.sqlite3_load_extension returns with a 1 (SQLITE_ERROR) and a null errmsg

Are you using PackageReference or packages.config?

PackageReference

If you are using mobile platforms, are you on classic/legacy Xamarin or on .NET 6 and higher?

N/A

Sometimes other packages using SQLitePCLRaw cause problems when they are mixed together. What other packages are you including in your project?

Just SQLitePCLRaw.bundle_green & SQLitePCLRaw.provider.dynamic_cdecl. We also have a native SqliteExtensions dll that we're trying to load.

How can we reproduce the problem you are seeing? Your issue will get attention much faster if you attach a minimal reproduction sample project.

Basically inspecting SQLitePCLRaw.batteries_v2.dll in the netstandard2.0 and net461 folders using ILDasm

@ericsink
Copy link
Owner

ericsink commented Nov 2, 2022

This may be similar to #490

@WilliamXieMSFT
Copy link
Author

It'd be nice to use the netstandard2.0 dll, but our current workaround is to explicitly use the one for net461.

@ericsink
Copy link
Owner

ericsink commented Nov 7, 2022

Taking a second look at this, I think I misunderstood. And unless I misunderstanding yet again, I don't think the nativelibrary code is actually related to the problem.

The real issue here is that the version of the provider used for net6.0 is compiled without support for load_extension.

The code that generates providers has a flag to allow load_extension to be turned on or off:

unsafe int ISQLite3Provider.sqlite3_load_extension(sqlite3 db, utf8z zFile, utf8z zProc, out utf8z pzErrMsg)
{
<#
if (FEATURE_LOADEXTENSION == "FEATURE_LOADEXTENSION/true")
{
#>
fixed (byte* p_zFile = zFile, p_zProc = zProc)
{
var rc = NativeMethods.sqlite3_load_extension(
db, p_zFile, p_zProc,
out var p_zErrMsg);
pzErrMsg = utf8z.FromPtr(p_zErrMsg);
return rc;
}
<#
}
else
{
#>
pzErrMsg = utf8z.FromPtr(null);
return raw.SQLITE_ERROR;
<#
}
#>
}

And the gen_providers program sets this flag depending on the various cases. For several common situations, including the one you are getting with net6.0, it's turned off:

gen_provider s s (Some subname_funcptrs_win) "Cdecl" "dllimport" "FEATURE_WIN32DIR/true" "FEATURE_FUNCPTRS/callingconv" "FEATURE_KEY/false" "FEATURE_LOADEXTENSION/false"

But I don't think there is a good reason why it should be. I think I incorporated this feature flag when I implemented load_extension simply to minimize the risk or chance of regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants