There is a subtle difference between weakly (strongly) typed programming languages and dynamically (statically) typed languages.
The strong/weak classification refers to type checking, and whether type errors are always found. If all type errors are found (either at run time or compile time), then the language is strongly typed. If few type errors are checked, then the language is considered to be weakly typed.
In this sense, no language is truly strongly typed, even Ada allows type checking to be suspended in certain cases. Pascal and Java are nearly strongly typed, while C and C++ are weakly typed because they allow passing parameters of unknown types to functions.
The static/dynamic axis refers to when a variable is bound to its type. Statically typed languages require variables to be bound to their types at compile time, thus there is often need to declare the type of the variable in the code. Dynamically typed languages, on the other hand, bind the variables to their types only when a value is assigned to a variable, thus allowing a variable to hold values of different types at different points in a programs execution.
Java, C, C++, and even Perl (to a certain extent) are statically bound languages, while APL, SNOBOL, and Ruby are dynamically bound languages.
Robert W. Sebesta, Concepts of Programming Languages, 4th Ed.