Python Forum
Integration of Python and C using .dll files
Thread Rating:
  • 2 Vote(s) - 2.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Integration of Python and C using .dll files
#1
To whom it may concern,

I am a student working on a senior design project to create a new software system to collect and display data from a particular data acquisition unit.  The company that created the unit has provided a universal library that works with c,c#,vb, and .net (I think).  I am presently trying to use python to accomplish this task.  Right now I am just trying to connect to the data acquisition unit using their universal language in order to receive temperature data.  I have imported their .dll file and can call the function using ctypes.  However, the function is set up to return an error message and pass temperature data as a float through an in-out variable.  So, my question is this, how do I get the value from an argument in a function that I called?  In general, it looks kind of like this:

error_code = dll.Function_name( integer, integer, integer, float *variable I need*, integer)

I've been using ctypes to create ctypes.c_int and ctypes.c_float to try to create the necessary arguments, but I cannot seem to get them to actually turn into a value.  When I print the value, it prints ctypes.c_int(0) or whatever integer I try to make.

So, I guess that's two questions.

1) How do I get the value that should be passed in and then passed back out of the function?
2) Why are the ctypes integers and floats not actually making integers and float variables?

Thank you in advance,

Zach
Reply
#2
Collecting temperature data is a very simple process.
In all of the units that I created, the data acquisition was done in isolation, using C
and then transmitted to a display unit through a serial interface, either by USB or
by I2C. Is this by any chance your setup, with the output of the serial port feeding
a dll?

If that is what you have, you may be far better off tapping the serial port directly and
forgetting about a dll. If you can do it this way (only if you have access to the serial interface)
you can create a unit that will run on any operating system that supports python.

What have you got for hardware?
Reply
#3
Larz60,

I'm using an OM-USB-TC daq from Omega.  And I have done it through serial connection before.  However, the company is loath to give out communication protocol.  When I contacted Omega for support on this topic, they basically told me "python isn't supported, go look at the universal library."  In addition, the company that I am working with for this senior design project already has calibration data files from Omega's software and using Omega's Universal Library allows for them to use those calibration files.

Thanks,
Zach
Reply
#4
The manuals are here: http://www.omega.com/pptst/OM-USB-TC.html#manuals
It has USB in the name, so that has to be an easy setup.
I'd try getting it to work with putty, where you can easily change the serial protocol
until you get all the parameters correct.
Once you've done that take a look at the PySerial or PYUSB packages one should be suitable
for your needs. When you're able to gather data, there are lots of ways to display the data
using several math packages available.

from page 8 of the user manual:

Quote:Connecting a OM-USB-TC to your computer is easy
Installing a data acquisition device has never been easier.


The following guide has a huge setion on hook-up: http://www.omega.com/manuals/manualpdf/M4830.pdf
Reply
#5
Larz60+,

I appreciate the quick responses.

However, it's not really feasible to try to guess and check the baud rate, stop bits, and parity of the device.  I already know that I can communicate fine with the device using the software that Omega provides, but that software cannot satisfy the requirements that I have for this project.  I have looked into Pyusb and trying to do communication that way, but I simply don't have enough time to try to guess and check.  And, it was my understanding that the company would not give out the information on how to hard code it myself.  This means that I have to try to use the universal library that they have developed due to the fact that it has all of the leg work coded into it.  All I need is to get the value from that variable, but I am unaware as to how to do so.  I've been trying to figure this out for about three weeks now, and this is the last option that I really have to finish this portion of the project on time.  The only other thing I can think of is trying to write a c++ file to return that variable and then call that from python, but I lack the necessary software to call and build .dll files.

Thanks,
Zach
Reply
#6
If you must use a dll, you can find out some of what it does with ilspy: http://ilspy.net/

here are some of it's features:

ILSpy Features

Assembly browsing
  • IL Disassembly
  • Support C# 5.0 "async"
  • Decompilation to C#
  • Supports lambdas and 'yield return'
  • Shows XML documentation
  • Decompilation to VB
  • Saving of resources
  • Save decompiled assembly as .csproj
  • Search for types/methods/properties (substring)
  • Hyperlink-based type/method/property navigation
  • Base/Derived types navigation
  • Navigation history
  • BAML to XAML decompiler
  • Save Assembly as C# Project
  • Find usage of field/method
  • Extensible via plugins (MEF)
  • Assembly Lists
That's about the extent of what I can offer

There's another one here that looks pretty good: http://www.jetbrains.com/decompiler/
Reply
#7
It would be helpful if you would post the code you have so far (between the code tags) and the actual Traceback (between the error tags).
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply
#8
Larz60+,

Thanks for your help, but neither of the options presented could open this file, and I don't know why. The second simply said it wasn't supported.

Thanks for all of your help, though.

sparkz_alot,

This is the code that I have presently.  I don't think it will help you all that much because the error generated is not in python, its an error code coming from the function itself as it actually only returns errors (or 0 if no errors).  However, I need to access the variable "testVal" after running the imported dll file.  That's the part I don't know how to do. 



# import all necessary libraries
import ctypes
import time
from ctypes import *
import os
import usb.core as usbc
import usb.util as usbu

# Step 1: Locate the cbw32.dll file

#This loop looks through the dierectory starting in the Program Files (x86)
#and finds the file path to the cbw32.dll file necessary for the Universal
#Library and names it path

path = '' #initialize path to be used later

import os
for root, dirs, files in os.walk('E:\Program Files (x86)'):
    for name in files:
        if 'cbw64.dll' in name:
            print(root + '\cbw64.dll')
            path = root + '\cbw64.dll'

# Step 2: import the .dll file from the Omega Universal Library
dll = cdll.LoadLibrary(path)

# Test the function
boardNum=ctypes.c_int(0)
chan=ctypes.c_int(1)
scale=ctypes.c_int(0)
testVal=ctypes.c_float(0)
option=ctypes.c_int(0)

#boardNum=0
#chan=0
#scale=0
#testVal=0.0
#option=0

for num in range(0,100):
    test2 = dll.cbTIn(boardNum,chan,scale,testVal,option)
    print(test2)
    time.sleep(1)
If I run the program using the ctypes definitions for the integers, I get an error code "35" which corresponds to:
Error:
An invalid (NULL) pointer was passed as an argument/parameter to a function or method.
However, if I run the code without using the ctypes definitions I get an error code from python saying:

Error:
Traceback (most recent call last):   File "<ipython-input-1-590ecd1f49cf>", line 1, in <module>     runfile('E:/Users/Zachary/documents/Senior Design Python and Daq/DaqComV1p1.py', wdir='E:/Users/Zachary/documents/Senior Design Python and Daq')   File "E:\Users\Zachary\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile     execfile(filename, namespace)   File "E:\Users\Zachary\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile     exec(compile(f.read(), filename, 'exec'), namespace)   File "E:/Users/Zachary/documents/Senior Design Python and Daq/DaqComV1p1.py", line 48, in <module>     test2 = dll.cbTIn(boardNum,chan,scale,testVal,option) ArgumentError: argument 4: <class 'TypeError'>: Don't know how to convert parameter 4
Thank you,

Zach

Zach
Reply
#9
There must be a line number associated with: An invalid (NULL) pointer was passed as an argument/parameter to a function or method.
You don't make errors go away by not importing, you need to fix the error.

The second error shows where the error is occurring -- line 48 -- 4th argument
testVal is the bad guy. It's obviously not the correct type.


which is now line 41 -- did you remove code before posting?
Reply
#10
Larz60+,

Yeah, I some comments on the top because I figured it would help make the code more clear.  I forgot that it gave line numbers.  Sorry about that.  All I removed was:


# -*- coding: utf-8 -*-
"""
Created on Sun Mar  5 10:42:35 2017

@author: Zach
"""
So, starting with the first error (the Null), there isn't a line error with that because that is an error that is returned from the .dll file.  All the .dll file returns is error codes (or a 0 if it executes without an error).  So that would be an error with the cbTIn() function at that line.  Unfortunately, I don't know what variable is considered "NULL" as all of them should have been defined using c_int or c_float.

As far as the second set of errors, it is the testVal variable that is causing the errors.  That is the value that I am trying to read once the cbTIn() function is done executing.  That is really where my question is, how do I get that value?  I can't simply give the function an undefined variable and then call it later, then I get an error that says that the variable is undefined.  It would be a ton easier if the cbTIn() function just returned the value, but it doesn't.  And, I am limited by the fact that it is the coding provided by Omega and I cannot seem to access the file such that I can see exactly what it is doing.

Thanks again for all of your help,

Zach
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020