我有一个名为runner.py的文件,它有很多调用市场DLL的函数.

#Imports para execução da DLL
import time
import gc
from ctypes import *
from ctypes.wintypes import UINT
import struct
from datetime import*
import sys
import functions
from threading import Thread

rotPassword = '' 
accountID   = '' 
corretora   = '' 

profit_dll = WinDLL('./ProfitDLL64.dll')
profit_dll.argtypes  = None

def printPosition():
    global profit_dll
    global corretora, accountID

    asset = 'asset'
    bolsa = 'f'
    thisCorretora = corretora
    acc_id = accountID    
    priceToReturn = 0

    result = profit_dll.GetPosition(c_wchar_p(str(acc_id)), c_wchar_p(str(thisCorretora)), c_wchar_p(asset), c_wchar_p(bolsa))

    print(f'here {result}')    
    return result
    
    n_qtd = result[0]

    if (n_qtd == 0):
        print('Nao ha posicao para esse ativo')        
        return priceToReturn
    else:
        n_tam = result[1]       

        arr = cast(result, POINTER(c_char))
        frame = bytearray()
        for i in range(n_tam):
            c = arr[i]
            frame.append(c[0])
        
        start = 8

        for i in range(n_qtd):
            corretora_id = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            acc_id_length = struct.unpack('h', frame[start:start+2])[0]
            start += 2
            account_id = frame[start:start+acc_id_length]
            start += acc_id_length

            titular_length = struct.unpack('h', frame[start:start+2])[0]
            start += 2
            titular = frame[start:start+titular_length]
            start += titular_length

            ticker_length = struct.unpack('h', frame[start:start+2])[0]
            start += 2
            ticker = frame[start:start+ticker_length]
            start += ticker_length

            intraday_pos = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            price = struct.unpack('d', frame[start:start + 8])[0]       
            priceToReturn = str(price)     
            start += 8

            avg_sell_price = struct.unpack('d', frame[start:start + 8])[0]
            start += 8

            sell_qtd = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            avg_buy_price = struct.unpack('d', frame[start:start + 8])[0]
            start += 8

            buy_qtd = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            custody_d1 = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            custody_d2 = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            custody_d3 = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            blocked = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            pending = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            allocated = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            provisioned = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            qtd_position = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            available = struct.unpack('i', frame[start:start+4])[0]
            start += 4

            print(f"Corretora: {corretora_id}, Titular: {str(titular)}, Ticker: {str(ticker)}, Price: {price}, AvgSellPrice: {avg_sell_price}, AvgBuyPrice: {avg_buy_price}, SellQtd: {sell_qtd}, BuyQtd: {buy_qtd}")

        return priceToReturn

def dllStart():    
    try:
        global profit_dll
        key = input("Chave de acesso: ")
        user = input("Usuário: ") # preencher com usuário da conta (email ou documento)
        password = input("Senha: ") # preencher com senha da conta
        
        bRoteamento = True
        
        if bRoteamento :            
            result = profit_dll.DLLInitializeLogin(c_wchar_p(key), c_wchar_p(user), c_wchar_p(password), stateCallback, historyCallBack, orderChangeCallBack, accountCallback,
                                              newTradeCallback, newDailyCallback, priceBookCallback,
                                              offerBookCallback, newHistoryCallback, progressCallBack, newTinyBookCallBack)
        else :
            result = profit_dll.DLLInitializeMarketLogin(c_wchar_p(key), c_wchar_p(user), c_wchar_p(password), stateCallback, newTradeCallback, newDailyCallback, priceBookCallback,
                                                 offerBookCallback, newHistoryCallback, progressCallBack, newTinyBookCallBack)

        profit_dll.SendSellOrder.restype = c_longlong
        profit_dll.SendBuyOrder.restype = c_longlong
        profit_dll.SendStopBuyOrder.restype = c_longlong
        profit_dll.SendStopSellOrder.restype = c_longlong
        profit_dll.SendZeroPosition.restype = c_longlong
        profit_dll.GetAgentNameByID.restype = c_wchar_p
        profit_dll.GetAgentShortNameByID.restype = c_wchar_p
        profit_dll.GetPosition.restype = POINTER(c_int)
        profit_dll.SendMarketSellOrder.restype = c_longlong
        profit_dll.SendMarketBuyOrder.restype = c_longlong

        print('DLLInitialize: ' + str(result))
        wait_login()
      
    except Exception as e:
        print(str(e))

if __name__ == '__main__':    
    try:
        dllStart()

        strInput = ''        

        while strInput != "exit":
            strInput = input('Insira o comando: ')
            if strInput == 'subscribe':
                subscribeTicker()
            elif strInput == 'unsubscribe':
                unsubscribeTicker()
            elif strInput == 'offerbook':
                subscribeOffer()
            elif strInput == 'position':
                printPosition()
            elif strInput == 'lastAdjusted':
                printLastAdjusted()
            elif strInput == 'buystop' :
                buyStopOrder()
            elif strInput == 'sellstop':
                sellStopOrder()
            elif strInput == 'cancel':
                cancelOrder()
            elif strInput == 'changeOrder':
                changeOrder()
            elif strInput == 'cancelAllOrders':
                cancelAllOrders()
            elif strInput == 'getOrders':
                getOrders()
            elif strInput == 'getOrder':
                getOrder()
            elif strInput == 'selectOrder':
                selectOrder()
            elif strInput == 'cancelOrder':
                cancelOrder()
            elif strInput == 'getOrderProfitID':
                getOrderProfitID()
            elif strInput == 'getAllTickersByStock':
                getAllTickersByStock()           
            elif strInput == 'getOld':
                getSerieHistory()        
            elif strInput == 'account':
                getAccount()         
            elif strInput == 'myBuy':
                sendBuyOrder()               
    except KeyboardInterrupt:                
        pass            

我在呼叫时得到的正确日志(log):

<ctypes.wintypes.LP_c_long object at 0x000001714E9CABC0>

当直接运行runner.py并呼叫printPosition()时,一切正常,它返回我需要的(上面的对象).
不过,我需要在一个单独的文件中导入这个printPosition才能调用它.在执行此操作时,我只收到了一个号码,而没有收到我需要的对象.

import socket, base64
import re
import sys
from operator import neg
from datetime import datetime
import profitrunner
import time
import gc
from ctypes import *
from ctypes.wintypes import UINT
import struct

def calculate_pos():
    memory_address = profitrunner.printPosition()       

    print(heapPosition)

    # I though on doing but did not work:  
  
    arr = cast(memory_address, POINTER(c_char))


来自以下位置的日志(log):

2015042512
2015042656
2015042800
2015042944
2015043088
2015043232

来自GetPosition个给予的文档如下所示:

Function that returns the position for a given ticker. Returns a data structure specified below. With full size (90 + N + T + K) bytes:

function GetPosition(
    pwcIDAccount   : PWideChar;
    pwcIDCorretora : PWideChar;
    pwcTicker      : PWideChar;
    pwcBolsa       : PWideChar) : Pointer; stdcall;

enter image description here

推荐答案

你需要这样的东西:

import ctypes as ct

profit_dll = ct.WinDLL('./ProfitDLL64.dll')
profit_dll.GetPosition.argtypes = ct.c_wchar_p, ct.c_wchar_p, ct.c_wchar_p, ct.c_wchar_p
profit_dll.GetPosition.restype = ct.POINTER(ct.c_int)

result = profit_dll.GetPosition(acc_id, thisCorretora, asset, bolsa)

返回类型只有Pointer,这不是描述性的,但是在注释中提供的.zip中,返回类型是POINTER(c_int),所以我使用了它.如果为函数正确设置了.argtypes,则不需要将每个参数都包装在C类型中,但profitDLL.py并非如此.确保调用dllStart()来设置返回类型,但最好 for each 函数正确设置.argtypes.restype,以便通过ctypes进行更好的错误判断.

Python相关问答推荐

合并其中一个具有重叠范围的两个框架的最佳方法是什么?

使用Curses for Python保存和恢复终端窗口内容

如何才能将每个组比上一组增加N %?

Python中两个矩阵的自定义Hadamard风格产物

如何将Matplotlib的fig.add_axes本地坐标与我的坐标关联起来?

如果索引不存在,pandas系列将通过索引获取值,并填充值

如何计算两极打印机中 * 所有列 * 的出现次数?

比较两个数据帧并并排附加结果(获取性能警告)

Gekko:Spring-Mass系统的参数识别

如何避免Chained when/then分配中的Mypy不兼容类型警告?

输出中带有南的亚麻神经网络

为什么默认情况下所有Python类都是可调用的?

将输入聚合到统一词典中

Django admin Csrf令牌未设置

从Windows Python脚本在WSL上运行Linux应用程序

为什么\b在这个正则表达式中不解释为反斜杠

使用特定值作为引用替换数据框行上的值

在不同的帧B中判断帧A中的子字符串,每个帧的大小不同

在matplotlib中使用不同大小的标记顶部添加批注

Numpyro AR(1)均值切换模型抽样不一致性