.NET application closes without error on using library methods - c#

I have a C++ DLL Library. I'm testing the DLL with a C# Project with NET Framework 4.0. In the C++ DLL I'm using some libraries, like POCO, Boost, ODBC, SQLite, SOCI...
It was doing great until I decided to replace the SOCI interface with the POCO one to reduce the number of libraries loaded in the library.
I compiled the PocoData, PocoDataODBC and added them, together with the headers, into the project. The project compiles OK, creates the DLL, and the DLL passes the Dependency Walker tests.
But something strange happens when using the DLL from the .NET Project. The app just closes when executing the DLL methods that contains the Poco::Data part to connect with the database.
There is no exception or error thrown. Not even "application just crashed" from windows. It just stop running and the Visual Studio returns to normal just like if it ended correctly.
I isolated the error and it's enought with any use or call inside the PocoData library to do this error. I can use the library until it tries to use a method that has any call to this. For example:
Session session("ODBC", conn);
Or even this alone:
Poco::Data::RecordSet rs();
So every time the C# calls a method that contains anything from the Poco::Data in the DLL it fails.
Any idea what can be happening?
Windows events log something when the app makes the error, I don't know if it's relevant. It raises two events, the first one is a system hour change between same value (strange), type: Kernel-General.
The second one (about 10 seconds later) is Service Control Manager level Information:
Service Windows Error Reporting Service entered in running state.

Related

Bruel & Kjaer 2250 SDK - How to setup a C# project from scratch?

I'm trying to write a C# project that makes use of Bruel & Kjaer 2250 SDK. The SDK installer installs a VisualStudio 2015 Windows Form C# project that I'm able to build.
The next step for me was to create a similar project from scratch, so trying to do this and following litterally the BK instructions what happens is that I'm not able to create an instance of of class RemoteAPI in BK.BasicEnv.Application namespace.
I get an exception that tells me these informations:
An unhandled exception of type 'System.NullReferenceException'
occurred in BasicEnvRemoteAPI.dll
Additional information: RemoteAPI - Construction: No Instance of
EnvOfficeModel.
The constructor call is very simple:
private RemoteAPI api;
...
api = new RemoteAPI();
So the ctor of RemoteAPI is failing because an instance of EnvOfficeModel is missing to it,
I've googled a lot and made some tests but the result is always the same for my own project while the B&K example is correctly starting and is able to create an instance of the RemoteAPI class.
I also tried to compare the two projects and I'm not able to find a different setting, then I tried to search the B&K installed files and the registry for some hint about the possible causes of this behaviour, but no way ....
If some of you had the same problem and could perhaps drive me to the correct information to solve this problem will be a great thing.
I know that also a REST interface is available to communicate with BK2250 but I would like to use the native communication driver if possile.
Thank you and kind regards.
I encountered the issue today,
Verify that you imported the dll in the project correctly (Should appear under References if not it's probably the second issue)
Verify that you are using the .NET Framework and not the .NET Core
I managed to get it working with a Windows Form application using the .NET Framework 4.7.2

Using external DLL's in C# COM-DLL project for MS-Access usage

The user's main application is ms-access (with ms-sql server). Ton of code in vba.
One of the main features i have to manifest is controlling my client's voip telephony. My plan is to make a COM DLL that the ms-access can use.
As of now, i've managed to write a C# project (vs2019 .net framework) that handles the voip pbx well, using json, and do all missions necessary, such as invoking calls, sending sms, get calls list, recodings list, get recordings wav files and convert them to mp3. I use Newtopsoft.Json and NAudio.Lame.
BUT it only works as a standalone .net project or exe.
As a COM DLL (class library) - ms-access can handle and use it UNTIL it gets to the part where the code uses ANY external dll's functionality - and it crashes (with newtonsoft) or just not working (with naudio), although the dll's are in the working folder.
I know i have to found a way to make these external dll's to work under the office (32bit) enviroment.
I was trying and guessing many code samples for a couple of days. I tried to follow the Assembly.Load/From/File examples to dynamically load and include the dll's, but i failed to assimilate it in my code or even to understand it enough.
I hope i'll get a solution here.
Thanks :)
Hum, I am able to create a COM object for use with Access. External library code (in my case Newton soft) for serializing data works just fine when that class code is used as a COM object from Access.
You don't mention if the other libraries are managed code, or external win32 .dll? I have however used un-managed .dll’s with a .net COM object, and then have consumed that from MS-access.
The only issue would be in project explorer is to ensure that you have a copy local setting = true for the external referenced .net .dll libraries. (And that is the default, so I am sure you do.
The next issue of course is of course is there any use of configuration files? (app.config) etc.? The reason for this of course that since your application is being launched with msaccess.exe, then the config and settings will be assumed to be in the office install folder, and not the local application. As a result, it not all so practical to move/copy those app.config files to the office folder where msaccess.exe resides. And the config file name will not only have to be in the same folder, but also named.
Msaccess.exe.config.
In place of
YourDotNet.exe.config
Now of course, if you build your project as a .net exec? Well then of course any config settings (application ones, not user) will be placed in this config file, and of course that file will have to be placed in the same folder as the .exe file.
So, one might add a “test” function (any function is a method of that class) to the class that you test/call from VBA to ensure that such settings are being seen and read (if you are using any settings).
Eg:
System.Reflection.Assembly.GetExecutingAssembly().Location + ".config"
So, return that to access and display this result.
The other issue is of course to FORCE your project to x86. I would not use “any” CPU. While this “may” work, since you are using access x32, then I would force compile your .net class to x86 as opposed to “any” CPU. This would also spit out some errors in case some of the external assemble(ies) are compared to a particular bit size and thus x86 settings will result in your class not consuming some of the external .net .dll’s.
Now you “note” that your project works as an .exe, and then “sort of” works as a class and “.dll” registered as a COM.
However, you don’t mention how you are “flipping” this from an .exe to a class, or do you simply have a .net “test” project that you run as an .exe, and it of course has a reference to that class .dll. And you NOT using “COM” for this testing.
If your test.exe program can use that external assembly?
Then I would create a test2 project, but this time around do NOT reference the assembly (as .net), but try using .net CreateObject(). (I think c# has this choice – vb.net certainly does).
So you could try + use a CreateObject() in this .net test sample, and thus test from .net as COM.
So this test .net program (one that has NOT referenced the assembly) would a intermediate test before you jump all the way into ms-access + VBA test code.
However, I would first test/check if an app.config file is being used here, since as noted when you flip to a COM object, and then create a instance of that object in Access/VBA?
Then the config file will NOT be used. You can in .net code force/change the app.config file in that running assembly, and I can’t seem to find my code example that does this. But I am not going to dig too hard until such time we confirm that you are using app.exe.config file here.
Edit
Out of cuirous, I googled naudio. It is managed code. So, that library should work just fine. If that project is compiled as "ANY CPU", you COULD try re-compile as x86, and also re-compile your test program as x86. Then when you create a COM object, then again compile that as x86.
As noted, I do quite a bit of COM stuff for ms-access, and I have without issue used Newtonsoft (for jason serializing/de-serializing) as a COM object that is consumed by ms-access.
And given that naudio is managed code then I don't see why it would be an issue. Any other 3rd party .dll's you using here? As a quick test, I would set all projects to x86. You seem to "mention" that "some" of the COM object works, but just not all.

Difficulty loading references after their rebuild

I'm writing applications and libraries simultaneously, and whenever I update a library it's a bit hard to get it recognized in the consumer application. I have open a separate Visual Studio instance for each library and application. After rebuilding a library I get in the consumer applications the warning/error below. I then either have to remove the reference and add it again. Or I have to clean and build the library solution 3-4 times, for such warning/error to disappear in the consumer app VS solution. Why would doing that 4 times make any difference to doing it 1 or 2 times..?
Would like to understand why this happens and if something can be done to make this work more smoothly?
Not sure if it's relevant but most of my applications I write in VB.NET and libaries in C# (as I'm in progress of changing everything to C#). I also have C# files from the libraries open in the consumer application VS, as it pops up during debugging. I also reference library dlls in the library project /bin/Debug folder, because I'm making a lot of changes at this point of development.
Warning 1 Namespace or type specified in the Imports 'somelibrary'
doesn't contain any public member or cannot be found. Make sure the
namespace or the type is defined and contains at least one public
member. Make sure the imported element name doesn't use any
aliases. 'local path'
..
Error 72 Unable to load referenced library 'path\somelibrary.dll': The
process cannot access the file because it is being used by another
process.
I'm writing applications and libraries simultaneously, and whenever I update a library it's a bit hard to get it recognized in the consumer application. I have open a separate Visual Studio instances for each library and application.
This is the fundamental source of your problem. Visual Studio does not like it when things outside it's control change. You should have a single solution open with all the relevant projects included in it. Then when something changes, all the projects which depend on that project will automatically be rebuilt. (At least, that's the default.)
After rebuilding a library I get in the consumer applications the warning/error below. I then either have to remove the reference and add it again. Or I have to clean and build the library solution 3-4 times, for such warning/error to disappear in the consumer app VS solution. Why would doing that 4 times make any difference to doing it 1 or 2 times..?
I don't think it has anything to do with how many times you clean and rebuild it, but how long it's been since you last made a change - you have to wait long enough for the VS instance building the dll to release the lock on the file, before the VS instance that is using it is able to access it.
When you build a project you lock up the .DLL file in the project you build it from, because that is the version of the assembly that the library instance of visual studio will use - however you are referencing that very same library in another process hence the reason you are seeing the error.
You have two options, keep having two instances and then close the two instances open them again and it will be fine.
What you are better off doing is adding the project itself you are referencing (and are getting the error for) to your solution. Then instead of referencing YourProject/bin/debug/assembly.dll add a reference to the local project via the Projects tab. This will then keep one process referencing the appropriate assemblies that it needs.
For every project in the solution check the project settings -> Compile tab -> advanced compile options... -> target framework(all configurations), see if they are all (for example) .NET framework 4. having different or the wrong framework might cause the problems you're having right now

Test compatibility between DLL in .NET

I'm working with Visual Studio 2010 and WinForms, .Net 4.0 (C#). I'm building an application with a lot of DLL (150). When I provide the application to my client, it's :
The Executable (.exe)
Dll files (.dll)
Each Dll is related to a module of the application, for example :
Ado.dll (provide access to database)
AccesManagement.dll (this module allows to manage users in the application)
Import.dll (this module allows the user to import data to the application)
etc.
When my client find a bug in the application, I correct it and I provide him impacted DLLs (in order to avoid him to test all the application). It can be for example the Import Dll.
The thing is, after some deliveries, we can have compatibility problems between Dll (a method that doesn't exist anymore in a new DLL for example). To avoid this problem, I would like to find a tool capable of checking compatibility between differents DLL.
I would like something like :
I specify the directory of the program to analyse (executable + Dll)
I launch the analyse
The program tells me for example : Error between Import.dll and Ado.dll, there is a class xxx in Import.dll expecting a method named xxx in the class xxx of Ado.dll
I've found some tools able to compare two versions of a Dll and provide added and removed members (Libcheck, ApiChange), but it's too complicated for me to do that because there are to many changes.
I think you may have a configuration management problem here -- at least as much as you've got a "compatibility" problem.
I'd recommend you find a way to track what versions of which assemblies each of your customers is using so that (1) you know what they're using when you decide what to ship, and (2) when they report bugs, you can replicate their setup (and thus, replicate their bug). If that sounds like a lot of work, it is. This is why a lot of software development shops take steps to ensure that there's a limit to the variation in setups among customers. It's nearly certain that you'll end up with some variation from customer-to-customer, but anything you can do to manage that problem will be beneficial.
Beyond the process implications, if you really need to create a "pluggable" environment, you probably need to create some interfaces for your objects to control the points where they connect, and you should probably look at Microsoft's Managed Extensibility Framework (MEF). MEF can help you manage the way objects "demand" behaviors from other objects.
I finally found a solution to my problem.
Since I'm :
Using SourceSafe and adding labels with the version of the application I'm building
Tagging each of my DLL with the version of the application
I built a program which is capable of :
Opening each Dll of a folder to read the version of the application in it
Getting from SourceSafe each project for the version specified in the DLL (With the functionnality "Get Label")
Then I just have to build the projet. If there is any compilation error, there is a compatibility problem.
This solution can avoid big compatibility problems, but you can still have compatibility problems which can't be seen with a compilation...

Which configuration do I need to use an external DLL in a WinForms application?

I'm working with an external DLL to consume an OCR device using a wrapper written by me. I have made tests on the wrapper and it works perfectly. But, when I use a WinForms project to consume the client class of the wrapper (located an another project), an error arises when calling C# methods imported from the DLL (using [DLLImport(...)]) saying that the DLL is not registered.
The error says:
"DLL Library function no found. Check registry install path."
All executions have been made in debug mode.
I've compared both projects configuration. The most relevant difference is that Test project is oriented to Any CPU and WinForms app only points to x86.
What could it be?
Updates
I've tried to register the dll using Regsvr32.exe but it didn't work. I thought about using Gacutil.exe but it required to uninstall all frameworks beyond .net framework 1.1...
I was wondering... at testing environment probably everything works well because testing framework has its dll's or executable files (or something like that) totally registered in windows, so those are trusted dlls. It is possible that debug generated dlls are not trusted by windows and therefore this problem arises?
I've created a form in the same troubling project and then I call the OCRWrapper from a button I've added to it. The OCR's worked!!. Unfortunately, it is difficult to rewrite the first form because we have invested a lot of hours in it; so, I'm still wondering what do I need to change in the troubling form...
I started again the form's development from scratch and added all the components related to it; everything worked well, the OCR read succesfully all data. When I loaded a combo box using a call to an ObjectContext and the error appeared again... I'm using an entity framework connected to Oracle.
I have a theory.
Let's imagine the following situation:
The ocr.dll depends on some other native DLL, lets call it other.dll [A].
In case this is a static dependency, you'll see it through Dependency Walker.
If its dynamic, you can use Sysinternals Process Explorer to monitor DLL loading in your working test project at run-time.
Your ADO.NET provider uses native DLLs under the hood (this is certainly true for ODP.NET) which depend on other.dll [B], which happens to have the same name but is actually a different DLL (or at least a different version) compared to other.dll [A].
Then, in run-time, this might happen:
When you connect to the database, ADO.NET provider dynamically loads its native DLLs, including the other.dll [B].
Then you try to call a function from OCR DLL. The P/Invoke tries to load the OCR DLL dynamically and succeeds, but the other.dll [B] is already loaded and ocr.dll tries to use some function from it, instead from other.dll [A] where it actually exists.
Welcome to DLL hell. So what can you do?
Try varying the order of calls to ocr.dll and ADO.NET provider to see anything changes. If you are (very) lucky, other.dll [A] might actually be a newer version that is still backward-compatible with other.dll [B] and things migh magically start to work.
Try another version of ADO.NET provider.
Try another ADO.NET provider.
Try getting a statically-linked ocr.dll from your vendor (i.e. no run-time dependency on other.dll [A]).
So, the call to the DLL works from a single button, but it does not work from a complex form. I'd say that there is an undefined behavior going on. The question remains whether it is you, that wrote the marshalling incorrectly, or it the DLL that is badly written.
Since we do not have access to the source code of the DLL, maybe you can post the prototype of the function, and all relevant struct definitions, and the DllImport line that you wrote for it?
Google can't find that error message which means(not definitely though :)) it is not a system message but a custom one coming from the code in the dll. So the dll does something dodgy. I guess it tries to double dispatch your call to another function internally.
Few things I suggest you try:
Run a x86 configuration. In the project properties -> Build tab set the platform to x86. this is assuming the dll is an x86 dll.
dumpbin /headers orc.dll
File Type: DLL
FILE HEADER VALUES
14C machine (**x86**)
4 number of sections
4CE7B6FC time date stamp Sat Nov 20 11:54:36 2010
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
This command line should tell you the bitness. In case it is a 64 bit run a 64 bit config instead but I bet it is 32 bit.
Do not include the dll in the project. I guess you do that already. Make sure the dll is in a folder that is in the %PATH% environment variable. When you run this at command prompt:
where ocr.dll
should tell you where the dll is. If it doesn't add the folder where the dll is installed to the %PATH%.

Categories