As the title says, I can't create a simple DLL. I'm using VS 2017 Community Edition Version 15.8.0. Here is the .dll code:
#include "stdafx.h"
#include "InvWin32App.h"
#include "$StdHdr.h"
void Prc1()
{
printf("ran procedure 1\n");
}
Here is the code for the header, per the MS way to do things:
#ifdef INVWIN32APP_EXPORTS
#define INVWIN32APP_API __declspec(dllexport)
#else
#define INVWIN32APP_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
INVWIN32APP_API void Prc1();
#ifdef __cplusplus
}
#endif
Here is the driver code: (Update: The driver program is an .exe program.)
#include "pch.h"
#include "InvWin32App.h"
int main()
{
Prc1();
}
It can't get any simpler than this. I get the following error message box when I try to run the code:
Unable to start program
program name.dll
program name.dll is not
a valid Win32 application
I can create .exe programs okay. I also got the error earlier this morning when I was running VS 2017 Version 15.7.5. Upgrading VS didn't do any good. I also tried to compile these as .c programs, but it didn't make any difference.
I had this problem on a couple occasions creating .exe programs using VS 2015. I don't recall what I did, but the problem disappeared. Any help would be appreciated.
TIA.
Right click the project in your solution explorer that is the project for the executable and click "Set as startup project."
Note that "is not a valid Win32 application" is not a compile error or a link error, it is the message you get when you tried to debug something that is not executable.
You can only start executables. Executables consume dlls. These should be two seperate projects with two sets of corresponding project settings.
I doubt that you are using a 32 bit dll. If you have your 64-bit Windows OS then you must have 64 bit version of this dll too. Sometimes, even you have 64-bit dll already then it could not run, so try the other version of this dll i.e. 32 bit version of this dll.
Along with this, make a small change in your unicurse.py file too.
PFB the code to add:
import ctypes
pdlib = ctypes.CDLL("pdcurses.dll")
though this line of code is somewhere inside some condition, but bringing on top will help you to check, if the dll has been loaded or not.
For any one joining the party at this time, I found that this error is caused when you try to run a 32bit dll using a 64bit python.
Now I won't go into the details as to why that won't work as above responses clearly describes that, but there are 2 solutions for this.
Install and 32bit python and use that to communicate with the dll.
Interprocess communication using the msl-loadlib library documentation
I used the second step which seemed more sustainable. The steps I am using below can be found in the documentation link above.
First is to create a server module that communicates with the 32 bit module
#server.py
from msl.loadlib import Server32
class Server(Server32):
# the init takes mandatory host and port as arguments
def __init__(self, host, port, **kwargs):
# using windll since this application is being run in windows, other options such as cdll exists
# this assumes that the dll file is in the same directory as this file
super(Server, self).__init__('tresdlib.dll', 'windll', host, port)
# define a function that is to be called with the required arguments
def fsl_command(self, com, doc):
#the server32 exposes the loaded dll as lib, which you can then use to call the dll functions and pass the required arguments
return self.lib.FSL_Command(com,doc)
Then we create a client module, that sends python requests to the server module
#client.py
from msl.loadlib import Client64
class Client(Client64):
def __init__(self):
# pass the server file we just created in module32=, the host am using is localhost, leave port as none for self assigning
super(Client, self).__init__(module32='server', host="127.0.0.1", port=None)
# define a function that calls the an existing server function and passes the args
def fsl_command(self, com, doc):
return self.request32('fsl_command', com, doc)
We are going to run this in a terminal but you can choose to call in another application
>>> from client import Client
>>> c = Client()
>>> c.fsl_command(arg1,arg2)
Related
For a project I need to include a DLL in Python. I'm using CPython3.4 and for including the dll I use pythonnet clr module (pythonnet-2.0.0.dev1-cp34-none-win_amd64.whl). In the dll I need a function that gives me a continuous update of a measurement. The dll is written in VB.net, the function that I need is shown below:
Public Sub AdviseStart(ByVal item As Integer, ByVal a As Action(Of Object)) Implements IConversation.AdviseStart
_parameterPoller.RegisterCallback(item, a)
End Sub
This is the code that I have written in python to call this function:
import clr
clr.AddReference('dll name')
from dll import SetupMonitor
monitor = SetupMonitor(None, None, None)
# call to the dll function
# Everytime the measurement is changed the "test" function should be executed
monitor.AdviseStart(8, test)
def test(data):
print("Value: " + str(data))
For the sake of my further project I want to use Python3.4 and not Ironpython.
I tested this code in python3.4 and 2.7 and I got this error:
No method matches given arguments
I am 100% sure that the error is from the AdviseStart function. Because when I use the same code with IronPython it works. In Ironpython this codes gives the output I expect:
Value: -74
The goal of this function is that everytime a new measurement is made the function "test" will be called. Everything for the measurement and calling is in the dll. Is there anyway I can make this function work in any CPython version?
There were some problems with integer arguments in the 64 bit builds. As far as I know that particular problem has been solved, but it would have been after that build you are using was released.
Try getting the source from github (https://github.com/renshawbay/pythonnet) and build that instead. To build and install it you just run "python setup.py install" (or any of the usual setup.py commands).
If it still doesn't work you can build a debug version by setting CONFIG="Debug" in setup.py and rebuilding. You will then be able to attach the visual studio debugger to your python process and step through the python.net code to see what signatures it's finding and why it's not matching with the arguments you're calling it with.
I'm attempting to get a development environment up and running for developing applications with Oracle C++ Call Interface (OCCI) in Visual Studio 2005.
My system specs are:
OS: Windows 7, 64-bit
Oracle: 11g release 11.2.0.2, 32-bit
Instant Client: BasicLite and SDK version 11.2.0.4 32-bit
Visual Studio 2005 Professional Edition version 8.0 with 32-bit tools enabled
I've followed this guide by Mark Williams and I got the example running but only in release mode. When I switch to debug mode the app will build, but when I run it I get the following error:
Problem signature:
Problem Event Name: APPCRASH
Application Name: OCCITest.exe
Application Version: 0.0.0.0
Application Timestamp: 53f5dfdd
Fault Module Name: KERNELBASE.dll
Fault Module Version: 6.1.7601.18229
The small example program that triggers this error is:
#include "employees.h"
using namespace std;
using namespace oracle::occi;
int main (void)
{
Employees *pEmployees = new Employees();
delete pEmployees;
return 0;
}
Employees::Employees()
{
user = "hr";
passwd = "hr";
db = "localhost:1521/service_name";
env = Environment::createEnvironment(Environment::DEFAULT);
try
{
con = env->createConnection(user, passwd, db);
}
catch (SQLException& ex)
{
cout << ex.getMessage();
exit(EXIT_FAILURE);
}
}
Employees::~Employees()
{
env->terminateConnection (con);
Environment::terminateEnvironment (env);
}
If I remove all calls to OCCI functionality the application doesn’t crash. That is, this program runs error-free:
#include "employees.h"
using namespace std;
using namespace oracle::occi;
int main (void)
{
Employees *pEmployees = new Employees();
delete pEmployees;
return 0;
}
Employees::Employees()
{
user = "hr";
passwd = "hr";
db = "localhost:1521/service_name";
cout<<"Look at me, I'm running"<<endl;
}
Employees::~Employees()
{}
In the guide Mark mentions that when running in debug mode, the linker should use the library file oraocci11d.lib. However, this file is not included in the Instant Client SDK version 11.2.0.4, so I’m using the input file oraocci11.lib for both the release and debug version.
I'm running out of ideas about how to proceed in solving this problem, and I would greatly appreciate any and all help.
If the Oracle DLL receives and/or passes objects such as std::string or any other object that either:
Manipulates the heap in any way, or
The objects could have differing internals between app and DLL,
then you have no choice but to use the correct library to link with. Otherwise you wind up with binary or heap incompatible objects being passed, which leads to what you're seeing now.
See here: http://docs.oracle.com/cd/E11882_01/appdev.112/e10764/install.htm#CBHGBBJI
The link above mentions both the debug import library and debug version of the DLL. Also this is stated at the link:
Applications that link to MSVCRTD.DLL, a debug version of Microsoft C-Runtime, /MDd compiler flag, should link with these specific OCCI libraries: oraocci11d.lib and oraocci11d.dll.
Since it took me quite some time to get the debug environment working I figured I'd answer my own question now that I did.
I got a variety of errors throughout the ordeal, but the error that I got most stuck on was an error saying:
'The application was unable to start correctly (0xc0150002).
Click OK to close the application.'
Also, I used http://www.dependencywalker.com which repeatedly told me that either oraocci11d.dll or a the following list of dll's could not be found.
API-MS-WIN-APPMODEL-RUNTIME-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ROBUFFER-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL
API-MS-WIN-SHCORE-SCALING-L1-1-1.DLL
DCOMP.DLL
IESHIMS.DLL
However, what was really missing was for the executable to be able to find oci.dll. I'm just mentioning the errors in case someone else runs into these.
Here is what was needed to make it work:
First of all, the Instant Client does not contain the oraocci11d.lib or oraocci11d.dll, so it is necessary to install the full Oracle Client.
Next, the following must be added to the PATH:
C:\Program Files\Oracle\11.2.0\OCI\lib\MSVC\vc8
C:\Program Files\Oracle\11.2.0\BIN
In Visual Studio, select Tools -> Options, unfold 'Projects and Solutions' and select VC++ Directories. In 'Show directories for' under:
Include Files add C:\Program Files\Oracle\11.2.0\OCI\include
Library files add C:\Program Files\Oracle\11.2.0\OCI\lib\MSVC\vc8
In the property page for your project under Configuration Properties -> Linker select Input and under Additional Dependencies add oraocci11d.lib (or oraocci11.lib for release mode). Then select debug/release mode in the Configuration Manager
I have a related problem in that I am successfully using oraocci12d.dll/msvcr100d.dll, but this in turn is using oci.dll/msvcr100.dll. ie, oci.dll is not using the debug version of msvcr100.
My program seems to run okay, but any memory leak reporting disappears on exit.
I'm following this sites tutorial:
http://progtutorials.tripod.com/COM.htm
Preliminary evidence: Visual Studio 2010, Windows 7 64 bit.
and I'm coding the examples in section 3. (Implementing a server DLL). I've typed out the code exactly as shown and I'm getting a "Class not registered" exception when executing this code on line 12 of the code outlined in section 4.1 (where the tutorial shows you how to access the DLL and I have followed 3.1 to the letter):
hresult hr = CoGetClassObject(CLSID_Car, CLSCTX_SERVER, NULL, IID_IClassFactory, (void **) &pClassFactory);
I tried running:
regsvr32 xyz.dll
with xyz.dll being the path to my dll in order to register the DLL. This resulted in an error trying to find DLLRegisterServer:
I have already run
REGEDIT
HKEY_CLASSES_ROOT\CarDLL.Car\CLSID = {d969084c-b758-43ea-a218-a48763167abd}
HKEY_CLASSES_ROOT\CLSID\{d969084c-b758-43ea-a218-a48763167abd} = CarDLL.Car
HKEY_CLASSES_ROOT\CLSID\{d969084c-b758-43ea-a218-a48763167abd}\InProcServer32 = C:\Users\wiocl2\Documents\Visual Studio 2010\Projects\CarDLL\debug\CarDLL.dll
that I assumed put all the GUIDS I needed in the registry (The GUIDS were generated by me).
I'm assuming that a function is needed to be added to the class that allows it to be registered but I don't know how to do this and how to go about figuring it out. I'm kind of lost, as I haven't been working with COM for very long. If someone could give me a shove in the right direction that would be helpful.
Edit: Oh yes, I moved
#include // contains definition of DEFINE_GUID
to the iid.h file from iid.cpp, otherwise I was getting unresolved external errors on the build.
The most likely explanation: you are building your COM object as a 32-bit DLL, but the registration has been performed as a 64-bit DLL.
The treatment: open an admin privileged command window and navigate to the location of your DLL (C:\Users\wiocl2\Documents\Visual Studio 2010\Projects\CarDLL\debug). Once there, type:
c:\windows\sysWOW64\regedit <filename of .reg file whose contents are displayed above>
This will run the 32-bit version of REGEDIT, ensuring that the registry entries are created in the correct part of the hive. To verify this, you should see an entry for {d969084c-b758-43ea-a218-a48763167abd} in HKLM\Software\Wow6432Node\Classes\CLSID, not HKLM\Software\Classes\CLSID.
DllRegisterServer is a method you can implement in your COM server DLL, and is required if you want to use regsvr32 to perform the same operation you are currently using the .REG approach for. The same caveat applies: for a 32-bit DLL, you'll need to invoke c:\windows\sysWOW64\regsvr32.exe.
And Yes! COM is still mostly alive and well :) At least there is still standard support for it in VS 2012.
Hope that helps.
I'm sure if it's possible, but I'd like to call the function which is defined in the exe file on Linux/Mac:
0x421ff0 ##my_func_doing_stuff#Initialize 4
Basically I'd like to add command line support which is not implemented and the UI is kind of drag&drop which is useless.
Note: I don't have access to the source of the file.
I've was playing with wine, objdump, uncc (trying to covert it into C again) and Python using pefile, SWIG and ctypes:
#!/usr/bin/python
from ctypes import *
import pefile, sys
pe = pefile.PE('my_file.exe')
print pe.dump_info()
my_exe = cdll.LoadLibrary('./my_file.exe')
but without success.
The error:
OSError: ./my_file.exe: invalid ELF header
reminded me that I can't call any of Windows functions under Linux without emulation?
So I'm looking for some other solutions. Probably it can be done somehow by emulating or debugging it under wine. But I'm not sure if there is any API for calling the specific functions.
Are there any existing solutions?
You can use winelib to load and link with the binary (since you need wine to provide a usable ABI), but keep in mind that this effectively turns your application into a Wine application.
i've to develop a stack trace walk to our win32 API plattform support to catch any exception with a behaviour of a JAVA stacktrace. Actually we got a full functional implementation for Linux plattforms.
First i've tried to implement a stackwalk using the win32 CaptureStackBackTrace API
mechanism. But this method is not integrated in the actually winbase header of mingw (using MSYS/MinGW 5.1.x) ...
So i decided tried use the dbgheader mechanism follwoing the instructions of this link :
http://sites.google.com/site/kenscode/prime-programs/boinc-with-mingw-on-win32
But i fail again and run into linker failures i could not solve. I think MinGW could not resolve the dbgheader library ....
DrMinGW is not an option for me, while it is a JIT Debugger, i've to implement a stack trace mechansim, for any exception occuring on runtime with a customizable log file tracebility like we know from JAVA ...
Has anyone get MSYS/MinGW runable with the win32 API in handshake? I will not change the compiler to the ugly MVC compiler instead of using MSYS/MinGW...
Thanks for any hint.
Best regards,
Christian
Check Mr. Edd's stack trace library at the following link. It will produce a nice stack frame listing and has specific code to support MinGW.
http://www.mr-edd.co.uk/code/stack_trace
His library uses dbghelp.dll, however, so you may get into some problems trying to compile it. As far as I know, MinGW doesn't include an import library for this DLL (see a old feature request here). I had success, however, creating one import library myself. You can do the same just using a .def file from the Wine project (check the previous link's attached files for one) and running the MingW utility dlltool:
dlltool -k -d dbghelp.def -l dbghelp.a
You can then include the resulting dbghelp.a file in your project. You won't probably like to have dependencies towards dbghelp.dll in your release builds, as the DLL itself is surely not redistributable.
Here is a method to walk the call stack using the Win32 API which you can call from MinGW.
http://www.codeproject.com/KB/threads/StackWalker.aspx
I got stack traces working in MingGW with Edd's dbg library, which is a successor to his minimal stack_trace library:
With msys2, this should get you a stack trace:
$ pacman -S mingw-w64-x86_64-edd-dbg
// main.cpp
#include <dbg/frames.hpp>
#include <dbg/symbols.hpp>
#include <iostream>
int main()
{
dbg::symdb db;
dbg::call_stack<64> traceback;
traceback.collect(0);
traceback.log(db, std::cout);
return 0;
}
$ g++ -ggdb main.cpp -ldbg
$ ./a.exe
0x0000000000402ee9: dbg::call_stack<64u>::collect(unsigned int) in C:\msys64\home\phil\stacktrace-example\a.exe
0x00000000004015f2: main in C:\msys64\home\phil\stacktrace-example\a.exe
0x00000000004013f8: __tmainCRTStartup in C:\msys64\home\phil\stacktrace-example\a.exe
0x000000000040151b: mainCRTStartup in C:\msys64\home\phil\stacktrace-example\a.exe
0x00007ffbb0838102: BaseThreadInitThunk in C:\WINDOWS\system32\KERNEL32.DLL
0x00007ffbb27cc5b4: RtlUserThreadStart in C:\WINDOWS\SYSTEM32\ntdll.dll
More about dbg can be found in the Wiki. The code is available here: https://bitbucket.org/edd/dbg/src