Как использовать команду cl?

1

Все, я нашел часть информации о том, как вызывать c файлы на python, в этих примерах: есть файл ac, который включает в себя множество других файлов заголовков, начало этих файлов c #include Python.h, тогда я что #include Python.h действительно включает в себя много других файлов заголовков, таких как pystate.h, object.h и т.д., поэтому я включаю все необходимые файлы заголовков. В среде cpp IDE он не обнаружил ошибок. То, что я пытаюсь сделать, это вызвать этот код c в python, поэтому from ctypes import *, тогда кажется, что dll должен быть сгенерирован кодом, таким как: cl -LD test.c -test.dll, но как использовать cl в этом случае? Я использовал cygwin: gcc, он работал нормально. Может ли кто-нибудь помочь мне с этим i.e.: вызвать C в python? Я могу прояснить ситуацию? Спасибо заранее!

Ну, теперь я чувствую, что важно сказать мне, что я сделал: Конечной целью, которую я хочу достичь, является: Я ленив, я не хочу переписывать эти коды c в python (что в некоторых случаях очень сложно для меня), поэтому я просто хочу сгенерировать dll файлы, которые может вызвать python. Я последовал примеру, указанному googleing "python call c", в этом примере есть две версии: linux и windows: Пример test.c:

#include <windows.h>
BOOL APIENTRY  
DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)  {  
    return TRUE;  
}  
__declspec(dllexport) int 
multiply(int num1, int num2)  {  
    return num1 * num2;  
}

Две версии: 1, Complie под linux

gcc -c -fPIC test.c  
gcc -shared test.o -o test.so 

Я сделал это в cygwin на моей системе vista, он отлично работает;:)

2, Скомпилировать под окнами:

cl -LD test.c -test.dll

Я использовал приглашение командной строки cl в командной строке Windows, это не сработает!

Это коды питона:

from ctypes import *   
import os  
libtest = cdll.LoadLibrary(os.getcwd() + '/test.so')  
print test.multiply(2, 2)  

Может ли кто-нибудь попробовать это и рассказать мне, что вы получаете? спасибо!

  • 0
    Это действительно не имеет никакого отношения к Python, вы просто спрашиваете, как запустить компилятор цепочки инструментов Microsoft в командной строке. Пожалуйста, рассмотрите возможность пометить свой вопрос соответствующим образом.
  • 0
    @Jim: может быть, я должен добавить: как сгенерировать dll-файл из c, чтобы python мог вызывать его, как в windows, IDE издает раздражающие шумы, которые не имеют ничего общего с самим кодом
Показать ещё 1 комментарий
Теги:
compiler-construction

1 ответ

2
Лучший ответ

Вы найдете параметры командной строки компилятора Microsoft С++ здесь.

Рассмотрим следующие переключатели для cl:

/nologo /GS /fp:precise /Zc:forScope /Gd

... и связать свой файл, используя

/NOLOGO /OUT:"your.dll" /DLL <your lib files> /SUBSYSTEM:WINDOWS /MACHINE:X86 /DYNAMICBASE

Пожалуйста, взгляните на то, что эти параметры означают в деталях, я просто перечислил общие. Тем не менее, вы должны знать об их эффекте, поэтому старайтесь избегать копирования и вставки и убедитесь, что это действительно то, что вам нужно - приведенная выше документация поможет вам. Это просто настройка, которую я использую более или менее часто.

Обратите внимание, что вы всегда можете открыть Visual Studio, настроить параметры сборки и скопировать вызовы командной строки из диалогового окна конфигурации проекта.

Edit: Хорошо, вот еще несколько советов, учитывая новую информацию, которую вы редактировали в свой исходный вопрос. Я взял пример кода вашей простой DLL и вставил его в исходный файл и сделал два изменения:

#include <windows.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
    return TRUE;  
} 

extern "C" __declspec(dllexport) int __stdcall multiply(int num1, int num2)
{
    return num1 * num2;  
} 

Прежде всего, я обычно ожидаю, что функции, экспортированные из DLL, будут использовать соглашение о вызове stdcall, просто потому, что это обычная вещь в Windows, и есть языки, которые по сути не могут справиться с cdecl, видя, что они знают только stdcall. Так что одно изменение я сделал.

Во-вторых, чтобы сделать экспорт более дружественным, я указал extern "C", чтобы избавиться от name mangling. Затем я приступил к компиляции кода из командной строки следующим образом:

cl /nologo /GS /Zc:forScope /Gd c.cpp /link /OUT:"foobar.dll" /DL kernel32.lib /SUBSYSTEM:WINDOWS /MACHINE:X86

Если вы используете инструмент DUMPBIN из набора инструментов Visual Studio, вы можете проверить свою DLL для экспорта:

dumpbin /EXPORTS foobar.dll

Видя что-то вроде этого...

ordinal hint RVA      name
    1    0 00001010 ?multiply@@YGHHH@Z

... вы можете заметить, что экспортированное имя получило повреждение. Обычно вам нужны четкие имена для экспорта, поэтому либо используйте файл DEF, чтобы указать экспорт более подробно, либо ярлык сверху.

Впоследствии я получаю DLL, которую я могу загрузить в Python следующим образом:

In [1]: import ctypes

In [2]: dll = ctypes.windll.LoadLibrary("foobar.dll")

In [3]: dll.multiply
Out[3]: <_FuncPtr object at 0x0928BEF3>

In [4]: dll.multiply(5, 5)
Out[4]: 25

Обратите внимание, что здесь я использую ctypes.windll, что подразумевает stdcall.

  • 0
    Я могу использовать cl сейчас, но он не будет работать, gcc работает нормально ...
  • 0
    Можете ли вы отредактировать свой вопрос, чтобы намекнуть на текущее состояние или вашу проблему, т.е. включая то, что вы уже пробовали до сих пор, какие сообщения об ошибках вы получаете, и что / почему вы думаете, что это не работает.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню